File: lazy_background_task_queue.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 (134 lines) | stat: -rw-r--r-- 5,762 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
// Copyright 2013 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_LAZY_BACKGROUND_TASK_QUEUE_H_
#define EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_

#include <stddef.h>

#include <algorithm>
#include <map>
#include <string>

#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "components/keyed_service/core/keyed_service.h"
#include "extensions/browser/extension_host_registry.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/lazy_context_id.h"
#include "extensions/browser/lazy_context_task_queue.h"
#include "extensions/common/extension_id.h"

namespace content {
class BrowserContext;
}

namespace extensions {
class Extension;
class ExtensionHost;

// This class maintains a queue of tasks that should execute when an
// extension's lazy background page is loaded. It is also in charge of loading
// the page when the first task is queued.
//
// It is the consumer's responsibility to use this class when appropriate, i.e.
// only with extensions that have not-yet-loaded lazy background pages.
class LazyBackgroundTaskQueue : public KeyedService,
                                public LazyContextTaskQueue,
                                public ExtensionRegistryObserver,
                                public ExtensionHostRegistry::Observer {
 public:
  explicit LazyBackgroundTaskQueue(content::BrowserContext* browser_context);

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

  ~LazyBackgroundTaskQueue() override;

  // Convenience method to return the LazyBackgroundTaskQueue for a given
  // `context`.
  static LazyBackgroundTaskQueue* Get(content::BrowserContext* context);

  // Returns true if the task should be added to the queue (that is, if the
  // extension has a lazy background page that isn't ready yet). If the
  // extension has a lazy background page that is being suspended this method
  // cancels that suspension.
  bool ShouldEnqueueTask(content::BrowserContext* context,
                         const Extension* extension) const override;

  // Returns true if the lazy background is ready to run tasks. This currently
  // means this and `ShouldEnqueueTask()` will return true at the same time. But
  // because of experiments on service workers needs to be separated out into
  // its own function.
  bool IsReadyToRunTasks(content::BrowserContext* context,
                         const Extension* extension) const override;

  // Adds a task to the queue for a given extension. If this is the first
  // task added for the extension, its lazy background page will be loaded.
  // The task will be called either when the page is loaded, or when the
  // page fails to load for some reason (e.g. a crash or browser
  // shutdown). In the latter case, `task` will be called with an empty
  // std::unique_ptr<ContextItem> parameter.
  void AddPendingTask(const LazyContextId& context_id,
                      PendingTask task) override;

 private:
  FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest, AddPendingTask);
  FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest, ProcessPendingTasks);
  FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest,
                           CreateLazyBackgroundPageOnExtensionLoaded);
  using PendingTasksList = std::vector<PendingTask>;
  // A map between a LazyContextId and the queue of tasks pending the load of
  // its background page.
  using PendingTasksMap = std::map<LazyContextId, PendingTasksList>;

  // ExtensionHostRegistry::Observer:
  void OnExtensionHostCompletedFirstLoad(
      content::BrowserContext* browser_context,
      ExtensionHost* host) override;
  void OnExtensionHostDestroyed(content::BrowserContext* browser_context,
                                ExtensionHost* host) override;

  // ExtensionRegistryObserver interface.
  void OnExtensionLoaded(content::BrowserContext* browser_context,
                         const Extension* extension) override;
  void OnExtensionUnloaded(content::BrowserContext* browser_context,
                           const Extension* extension,
                           UnloadedExtensionReason reason) override;

  // If there are pending tasks for `extension` in `browser_context`, try to
  // create the background host. If the background host cannot be created, the
  // pending tasks are invoked with nullptr.
  void CreateLazyBackgroundHostOnExtensionLoaded(
      content::BrowserContext* browser_context,
      const Extension* extension);

  // Called when a lazy background page has finished loading, or has failed to
  // load (host is nullptr in that case). All enqueued tasks are run in order.
  void ProcessPendingTasks(
      ExtensionHost* host,
      content::BrowserContext* context,
      const Extension* extension);

  // Notifies queued tasks that a lazy background page has failed to load.
  void NotifyTasksExtensionFailedToLoad(
      content::BrowserContext* browser_context,
      const Extension* extension);

  raw_ptr<content::BrowserContext, DanglingUntriaged> browser_context_;
  PendingTasksMap pending_tasks_;

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

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_