File: log_source_access_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 (172 lines) | stat: -rw-r--r-- 7,428 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
// Copyright 2017 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_API_FEEDBACK_PRIVATE_LOG_SOURCE_ACCESS_MANAGER_H_
#define EXTENSIONS_BROWSER_API_FEEDBACK_PRIVATE_LOG_SOURCE_ACCESS_MANAGER_H_

#include <map>
#include <memory>
#include <string>
#include <utility>

#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "components/feedback/redaction_tool/redaction_tool.h"
#include "components/feedback/system_logs/system_logs_source.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/api/feedback_private/access_rate_limiter.h"
#include "extensions/common/api/feedback_private.h"
#include "extensions/common/extension_id.h"

namespace extensions {

// Provides bookkeepping for SingleLogSource usage. It ensures that:
// - Each extension can have only one SingleLogSource for a particular source.
// - A source may not be accessed too frequently by an extension.
class LogSourceAccessManager {
 public:
  using ReadLogSourceCallback = base::OnceCallback<void(
      std::unique_ptr<api::feedback_private::ReadLogSourceResult>)>;

  explicit LogSourceAccessManager(content::BrowserContext* context);

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

  ~LogSourceAccessManager();

  // Call this to override the maximum burst access count of the rate limiter.
  static void SetMaxNumBurstAccessesForTesting(int num_accesses);

  // To override the default rate-limiting mechanism of this function, pass in
  // a TimeDelta representing the desired minimum time between consecutive reads
  // of a source from an extension. Does not take ownership of `timeout`. When
  // done testing, call this function again with `timeout`=nullptr to reset to
  // the default behavior.
  static void SetRateLimitingTimeoutForTesting(const base::TimeDelta* timeout);

  // Override the default base::Time clock with a custom clock for testing.
  void SetTickClockForTesting(const base::TickClock* clock) {
    tick_clock_ = clock;
  }

  // Initiates a fetch from a log source, as specified in `params`. See
  // feedback_private.idl for more info about the actual parameters.
  bool FetchFromSource(const api::feedback_private::ReadLogSourceParams& params,
                       const ExtensionId& extension_id,
                       ReadLogSourceCallback callback);

  // Each log source may not have more than this number of readers accessing it,
  // regardless of extension.
  static constexpr int kMaxReadersPerSource = 10;

 private:
  FRIEND_TEST_ALL_PREFIXES(LogSourceAccessManagerTest,
                           MaxNumberOfOpenLogSourcesSameExtension);
  FRIEND_TEST_ALL_PREFIXES(LogSourceAccessManagerTest,
                           MaxNumberOfOpenLogSourcesDifferentExtensions);

  // Contains a source/extension pair.
  struct SourceAndExtension {
    explicit SourceAndExtension(api::feedback_private::LogSource source,
                                const ExtensionId& extension_id);

    bool operator<(const SourceAndExtension& other) const {
      return std::make_pair(source, extension_id) <
             std::make_pair(other.source, other.extension_id);
    }

    // The log source that this handle is accessing.
    api::feedback_private::LogSource source;
    // ID of the extension that opened this handle.
    ExtensionId extension_id;
  };

  using ResourceId = int;

  // Returned when there was an error creating a new resource or looking for an
  // existing resource.
  static constexpr ResourceId kInvalidResourceId = 0;

  // Creates a new LogSourceResource for the source and extension indicated by
  // `source` and `extension_id`. Stores the new resource in the API Resource
  // Manager, and uses the resource ID as a key for a new entry in
  // `open_handles_`, with value being a SourceAndExtension containing `source`
  // and `extension_id`.
  //
  // Returns the nonzero ID of the newly created LogSourceResource, or
  // `kInvalidResourceId` if a new resource could not be created.
  ResourceId CreateResource(api::feedback_private::LogSource source,
                            const ExtensionId& extension_id);

  // Callback that is passed to the log source from FetchFromSource.
  // Arguments:
  // - extension_id: ID of extension that opened the log source.
  // - resource_id: Resource ID provided by API Resource Manager for the reader.
  // - delete_source: Set this if the source opened by `handle` should be
  //   removed from both the API Resource Manager and from `open_handles_`.
  // - callback: Callback for sending the response as a ReadLogSourceResult
  //   struct.
  // - response: Contains the result from an operation to fetch from system
  //   log(s).
  void OnFetchComplete(
      const ExtensionId& extension_id,
      ResourceId resource_id,
      bool delete_source,
      ReadLogSourceCallback callback,
      std::unique_ptr<system_logs::SystemLogsResponse> response);

  // Removes an existing log source handle indicated by `id` from
  // `open_handles_`.
  void RemoveHandle(ResourceId id);

  // Returns the number of entries in `open_handles_` with source=`source`.
  size_t GetNumActiveResourcesForSource(
      api::feedback_private::LogSource source) const;

  // Attempts to update the `last_access_time` field for the SourceAndExtension
  // |open_handles_[id]|, to record that the source is being accessed by the
  // handle right now. If less than `min_time_between_reads_` has elapsed since
  // the last successful read, does not update `last_access_times`, and instead
  // returns false. Otherwise returns true.
  bool UpdateSourceAccessTime(ResourceId id);

  // Keeps track of the last time each source was accessed by each extension.
  // Each time FetchFromSource() is called, the timestamp gets updated.
  //
  // This intentionally kept separate from `sources_` because entries can be
  // removed from and re-added to `sources_`, but that should not erase the
  // recorded access times.
  std::map<SourceAndExtension, std::unique_ptr<AccessRateLimiter>>
      rate_limiters_;

  // Contains all open handles, each uniquely identified by a ResourceId and
  // additionally described by a SourceAndExtension struct.
  std::map<ResourceId, std::unique_ptr<SourceAndExtension>> open_handles_;

  // Keep count of the number of reader handles (resources) for each source.
  std::map<api::feedback_private::LogSource, size_t> num_readers_per_source_;

  // For fetching browser resources like ApiResourceManager.
  raw_ptr<content::BrowserContext> context_;

  // Provides a timer clock implementation for keeping track of access times.
  // Can override the default clock for testing.
  raw_ptr<const base::TickClock> tick_clock_;

  // For removing PII from log strings from log sources.
  scoped_refptr<base::SequencedTaskRunner> task_runner_for_redactor_;
  scoped_refptr<redaction::RedactionToolContainer> redactor_container_;

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

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_API_FEEDBACK_PRIVATE_LOG_SOURCE_ACCESS_MANAGER_H_