File: extension_service.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 (469 lines) | stat: -rw-r--r-- 19,195 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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
// 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_EXTENSION_SERVICE_H_
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_

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

#include "base/auto_reset.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_multi_source_observation.h"
#include "base/scoped_observation.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/blocklist.h"
#include "chrome/browser/extensions/cws_info_service.h"
#include "chrome/browser/extensions/extension_management.h"
#include "chrome/browser/extensions/extension_telemetry_service_verdict_handler.h"
#include "chrome/browser/extensions/forced_extensions/force_installed_metrics.h"
#include "chrome/browser/extensions/forced_extensions/force_installed_tracker.h"
#include "chrome/browser/extensions/omaha_attributes_handler.h"
#include "chrome/browser/extensions/safe_browsing_verdict_handler.h"
#include "chrome/browser/profiles/profile_manager_observer.h"
#include "chrome/browser/upgrade_detector/upgrade_observer.h"
#include "components/sync/model/string_ordinal.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_creation_observer.h"
#include "extensions/browser/crx_file_info.h"
#include "extensions/browser/delayed_install_manager.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_host_registry.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registrar.h"
#include "extensions/browser/install_flag.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/uninstall_reason.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/manifest.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

class BlocklistedExtensionSyncServiceTest;
class Profile;
class ProfileManager;

namespace base {
class CommandLine;
class OneShotEvent;
}  // namespace base

FORWARD_DECLARE_TEST(BlocklistedExtensionSyncServiceTest,
                     SyncBlocklistedExtension);

namespace extensions {
class ChromeExtensionRegistrarDelegate;
class ComponentLoader;
class CorruptedExtensionReinstaller;
class DelayedInstallManager;
class ExtensionActionStorageManager;
class ExtensionAllowlist;
class ExtensionErrorController;
class ExtensionRegistry;
class ExtensionSystem;
class ExtensionUpdater;
class ExternalInstallManager;
class ExternalProviderManager;
class PendingExtensionManager;
enum class UnloadedExtensionReason;

// This is an interface class to encapsulate the dependencies that
// various classes have on ExtensionService. This allows easy mocking.
class ExtensionServiceInterface {
 public:
  virtual ~ExtensionServiceInterface() = default;

  // Returns an update for an extension with the specified id, if installation
  // of that update was previously delayed because the extension was in use. If
  // no updates are pending for the extension returns NULL.
  virtual const Extension* GetPendingExtensionUpdate(
      const std::string& extension_id) const = 0;

  // Attempts finishing installation of an update for an extension with the
  // specified id, when installation of that extension was previously delayed.
  // `install_immediately` - Whether the extension should be installed if it's
  //     currently in use.
  // Returns whether the extension installation was finished.
  virtual bool FinishDelayedInstallationIfReady(const std::string& extension_id,
                                                bool install_immediately) = 0;

  // Go through each extension and unload those that are not allowed to run by
  // management policy providers (ie. network admin and Google-managed
  // blocklist).
  virtual void CheckManagementPolicy() = 0;

  // Safe to call multiple times in a row.
  //
  // TODO(akalin): Remove this method (and others) once we refactor
  // themes sync to not use it directly.
  virtual void CheckForUpdatesSoon() = 0;

  // Whether a user is able to disable a given extension.
  virtual bool UserCanDisableInstalledExtension(
      const std::string& extension_id) = 0;

  virtual base::WeakPtr<ExtensionServiceInterface> AsWeakPtr() = 0;
};

// Manages installed and running Chromium extensions. An instance is shared
// between normal and incognito profiles.
class ExtensionService : public ExtensionServiceInterface,
                         public content::RenderProcessHostCreationObserver,
                         public content::RenderProcessHostObserver,
                         public Blocklist::Observer,
                         public CWSInfoService::Observer,
                         public ExtensionManagement::Observer,
                         public UpgradeObserver,
                         public ExtensionHostRegistry::Observer,
                         public ProfileManagerObserver {
 public:
  // Constructor stores pointers to `profile` and `extension_prefs` but
  // ownership remains at caller.
  ExtensionService(Profile* profile,
                   const base::CommandLine* command_line,
                   const base::FilePath& install_directory,
                   const base::FilePath& unpacked_install_directory,
                   ExtensionPrefs* extension_prefs,
                   Blocklist* blocklist,
                   ExtensionErrorController* error_controller,
                   bool autoupdate_enabled,
                   bool extensions_enabled,
                   base::OneShotEvent* ready);

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

  ~ExtensionService() override;

  // ExtensionServiceInterface implementation.
  //
  const Extension* GetPendingExtensionUpdate(
      const std::string& extension_id) const override;
  bool FinishDelayedInstallationIfReady(const std::string& extension_id,
                                        bool install_immediately) override;
  void CheckManagementPolicy() override;
  void CheckForUpdatesSoon() override;
  base::WeakPtr<ExtensionServiceInterface> AsWeakPtr() override;

  // ExtensionManagement::Observer implementation:
  void OnExtensionManagementSettingsChanged() override;

  // Initialize and start all installed extensions.
  void Init();

  // Called when the associated Profile is going to be destroyed, as part of
  // KeyedService two-phase shutdown.
  void Shutdown();

  // Performs action based on Omaha attributes for the extension.
  void PerformActionBasedOnOmahaAttributes(const std::string& extension_id,
                                           const base::Value::Dict& attributes);

  // Performs action based on verdicts received from the Extension Telemetry
  // server. Currently, these verdicts are limited to off-store extensions.
  void PerformActionBasedOnExtensionTelemetryServiceVerdicts(
      const Blocklist::BlocklistStateMap& blocklist_state_map);

  // Disable non-default and non-managed extensions with ids not in
  // `except_ids`. Default extensions are those from the Web Store with
  // `was_installed_by_default` flag.
  void DisableUserExtensionsExcept(const std::vector<std::string>& except_ids);

  // Returns whether a user is able to disable a given extension or if that is
  // not possible (for instance, extension was enabled by policy).
  bool UserCanDisableInstalledExtension(
      const std::string& extension_id) override;

  //////////////////////////////////////////////////////////////////////////////
  // Simple Accessors

  // Returns a WeakPtr to the ExtensionService.
  base::WeakPtr<ExtensionService> AsExtensionServiceWeakPtr() {
    return weak_ptr_factory_.GetWeakPtr();
  }

  // Returns profile_ as a BrowserContext.
  content::BrowserContext* GetBrowserContext() const;

  Profile* profile() { return profile_; }

  ForceInstalledTracker* force_installed_tracker() {
    return &force_installed_tracker_;
  }

  // TODO(crbug.com/404941806): Delete this method and use the KeyedService
  // directly.
  ExtensionAllowlist* allowlist() { return allowlist_; }

  //////////////////////////////////////////////////////////////////////////////
  // For Testing

  // Unload all extensions. Does not send notifications.
  void UnloadAllExtensionsForTest();

  // Reloads all extensions. Does not notify that extensions are ready.
  void ReloadExtensionsForTest();

  // Simulate an extension being blocklisted for tests.
  void BlocklistExtensionForTest(const std::string& extension_id);

  // Simulate an extension being greylisted for tests.
  void GreylistExtensionForTest(const std::string& extension_id,
                                const BitMapBlocklistState& state);

  void UninstallMigratedExtensionsForTest();

  bool HasShutDownExecutedForTest() const { return is_shut_down_executed_; }

#if defined(UNIT_TEST)
  void FinishInstallationForTest(const Extension* extension) {
    extension_registrar_->FinishInstallation(extension);
  }

  void ProfileMarkedForPermanentDeletionForTest() {
    OnProfileMarkedForPermanentDeletion(profile_);
  }
#endif

  // Load Extension Flags.
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  //
  // LINT.IfChange(LoadExtensionFlag)
  enum class LoadExtensionFlag {
    // --load-extension flag.
    kLoadExtension = 0,
    // --disable-extensions-except flag.
    kDisableExtensionsExcept = 1,

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

 private:
  // Loads extensions specified via a command line flag/switch.
  void LoadExtensionsFromCommandLineFlag(const char* switch_name);
#if BUILDFLAG(IS_CHROMEOS)
  void LoadSigninProfileTestExtension(const std::string& path);
#endif

  // ExtensionHostRegistry::Observer:
  void OnExtensionHostRenderProcessGone(
      content::BrowserContext* browser_context,
      ExtensionHost* extension_host) override;

  // content::RenderProcessHostCreationObserver:
  void OnRenderProcessHostCreated(content::RenderProcessHost* host) override;

  // content::RenderProcessHostObserver:
  void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;

  // Blocklist::Observer implementation.
  void OnBlocklistUpdated() override;

  // CWSInfoService::Observer implementation.
  void OnCWSInfoChanged() override;

  // UpgradeObserver implementation.
  void OnUpgradeRecommended() override;

  // ProfileManagerObserver implementation.
  void OnProfileMarkedForPermanentDeletion(Profile* profile) override;

  // Attempt to enable all disabled extensions which the only disabled reason is
  // reloading.
  void EnabledReloadableExtensions();

  // Signals *ready_ and sends a notification to the listeners.
  void SetReadyAndNotifyListeners();

  // Manages the blocklisted extensions, intended as callback from
  // Blocklist::GetBlocklistedIDs.
  void ManageBlocklist(const Blocklist::BlocklistStateMap& blocklisted_ids);

  // Used only by test code.
  void UnloadAllExtensionsInternal();

  // Disable apps & extensions now to stop them from running after a profile
  // has been conceptually deleted. Don't wait for full browser shutdown and
  // the actual profile objects to be destroyed.
  void OnProfileDestructionStarted();

  // Called when the initial extensions load has completed.
  void OnInstalledExtensionsLoaded();

  // Called when the Developer Mode preference is changed:
  // - Disables unpacked extensions if developer mode is OFF.
  // - Re-enables unpacked extensions if developer mode is ON and there are no
  // other disable reasons associated with them.
  void OnDeveloperModePrefChanged();

  // Logs a warning if --extensions-on-chrome-urls switch is used in Google
  // Chrome.
  void LogExtensionsOnChromeUrlsSwitchWarningIfNeeded();

  raw_ptr<const base::CommandLine> command_line_ = nullptr;

  // The normal profile associated with this ExtensionService.
  raw_ptr<Profile> profile_ = nullptr;

  // The ExtensionSystem for the profile above.
  raw_ptr<ExtensionSystem> system_ = nullptr;

  // Preferences for the owning profile.
  raw_ptr<ExtensionPrefs> extension_prefs_ = nullptr;

  // Blocklist for the owning profile.
  raw_ptr<Blocklist> blocklist_ = nullptr;

  raw_ptr<ExtensionAllowlist> allowlist_ = 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;

  // Manages external providers. Not owned.
  raw_ptr<ExternalProviderManager> external_provider_manager_ = nullptr;

  // Signaled when all extensions are loaded.
  const raw_ptr<base::OneShotEvent> ready_;

  // Our extension updater. May be disabled if updates are turned off.
  raw_ptr<ExtensionUpdater> updater_ = nullptr;

  base::ScopedMultiSourceObservation<content::RenderProcessHost,
                                     content::RenderProcessHostObserver>
      host_observation_{this};

  // Keeps track of loading and unloading component extensions.
  raw_ptr<ComponentLoader> component_loader_ = nullptr;

  // Set to true if this is the first time this ExtensionService has run.
  // Used for specially handling external extensions that are installed the
  // first time.
  bool is_first_run_ = false;

  // Set to true if the ExtensionService::Shutdown() has been executed.
  // Used in test to ensure the service's shutdown method has been called.
  bool is_shut_down_executed_ = false;

  // The controller for the UI that alerts the user about any blocklisted
  // extensions. Not owned.
  raw_ptr<ExtensionErrorController> error_controller_ = nullptr;

  // The manager for extensions that were externally installed that is
  // responsible for prompting the user about suspicious extensions. Not owned.
  raw_ptr<ExternalInstallManager> external_install_manager_ = nullptr;

  std::unique_ptr<ExtensionActionStorageManager>
      extension_action_storage_manager_;

  std::unique_ptr<ChromeExtensionRegistrarDelegate>
      extension_registrar_delegate_;

  // Helper to register and unregister extensions.
  raw_ptr<ExtensionRegistrar> extension_registrar_ = nullptr;

  // Needs `extension_registrar_` during construction.
  SafeBrowsingVerdictHandler safe_browsing_verdict_handler_;

  // Needs `extension_registrar_` during construction.
  ExtensionTelemetryServiceVerdictHandler
      extension_telemetry_service_verdict_handler_;

  // Needs `extension_registrar_` during construction.
  OmahaAttributesHandler omaha_attributes_handler_;

  // Tracker of enterprise policy forced installation.
  ForceInstalledTracker force_installed_tracker_;

  // Reports force-installed extension metrics to UMA.
  ForceInstalledMetrics force_installed_metrics_;

  // Schedules downloads/reinstalls of the corrupted extensions.
  raw_ptr<CorruptedExtensionReinstaller> corrupted_extension_reinstaller_;

  base::ScopedObservation<ProfileManager, ProfileManagerObserver>
      profile_manager_observation_{this};

  base::ScopedObservation<ExtensionHostRegistry,
                          ExtensionHostRegistry::Observer>
      host_registry_observation_{this};

  base::ScopedObservation<CWSInfoService, CWSInfoService::Observer>
      cws_info_service_observation_{this};

  raw_ptr<DelayedInstallManager> delayed_install_manager_;

  PrefChangeRegistrar pref_change_registrar_;

  base::WeakPtrFactory<ExtensionService> weak_ptr_factory_{this};

  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
                           DestroyingProfileClearsExtensions);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, SetUnsetBlocklistInPrefs);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, NoUnsetBlocklistInPrefs);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
                           BlocklistedExtensionWillNotInstall);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
                           UnloadBlocklistedExtensionPolicy);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
                           WillNotLoadBlocklistedExtensionsFromDirectory);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, ReloadBlocklistedExtension);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, RemoveExtensionFromBlocklist);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, BlocklistedInPrefsFromStartup);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
                           ManagementPolicyProhibitsEnableOnInstalled);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
                           BlockAndUnblockBlocklistedExtension);
  FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
                           CanAddDisableReasonToBlocklistedExtension);
  FRIEND_TEST_ALL_PREFIXES(::BlocklistedExtensionSyncServiceTest,
                           SyncBlocklistedExtension);
  FRIEND_TEST_ALL_PREFIXES(ExtensionAllowlistUnitTest,
                           ExtensionsNotAllowlistedThenBlocklisted);
  FRIEND_TEST_ALL_PREFIXES(ExtensionAllowlistUnitTest,
                           ExtensionsBlocklistedThenNotAllowlisted);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           GreylistedExtensionDisabled);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           GreylistDontEnableManuallyDisabled);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           GreylistUnknownDontChange);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           UnblocklistedExtensionStillGreylisted);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           GreylistedExtensionDoesNotDisableAgain);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           GreylistedExtensionDisableAgainIfReAdded);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           DisableExtensionForDifferentGreylistState);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           DisableExtensionWhenSwitchingBetweenGreylistStates);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           AcknowledgedStateBackFilled);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           ExtensionUninstalledWhenBlocklisted);
  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingVerdictHandlerUnitTest,
                           ExtensionUninstalledWhenBlocklistFetching);
  friend class ::BlocklistedExtensionSyncServiceTest;
  friend class SafeBrowsingVerdictHandlerUnitTest;
  friend class BlocklistStatesInteractionUnitTest;
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_