File: module_inspector.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 (163 lines) | stat: -rw-r--r-- 6,475 bytes parent folder | download | duplicates (7)
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
// 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 CHROME_BROWSER_WIN_CONFLICTS_MODULE_INSPECTOR_H_
#define CHROME_BROWSER_WIN_CONFLICTS_MODULE_INSPECTOR_H_

#include "base/containers/queue.h"
#include "base/functional/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/task/task_traits.h"
#include "base/timer/timer.h"
#include "chrome/browser/win/conflicts/inspection_results_cache.h"
#include "chrome/browser/win/conflicts/module_database_observer.h"
#include "chrome/browser/win/conflicts/module_info.h"
#include "chrome/services/util_win/public/mojom/util_win.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"

namespace base {
class SequencedTaskRunner;
}

// This class takes care of inspecting several modules (identified by their
// ModuleInfoKey) and returning the result via the OnModuleInspectedCallback on
// the SequencedTaskRunner where it was created.
//
// The inspection of all modules is quite expensive in terms of resources, so it
// is done one by one, in a utility process, only if it is needed (when
// StartInspection() is called).
//
// This class is not thread safe and it enforces safety via a SEQUENCE_CHECKER.
class ModuleInspector : public ModuleDatabaseObserver {
 public:
  // The amount of time before the |inspection_results_cache_| is flushed to
  // disk while the ModuleDatabase is not idle.
  static constexpr base::TimeDelta kFlushInspectionResultsTimerTimeout =
      base::Minutes(5);

  using OnModuleInspectedCallback =
      base::RepeatingCallback<void(const ModuleInfoKey& module_key,
                                   ModuleInspectionResult inspection_result)>;

  explicit ModuleInspector(
      const OnModuleInspectedCallback& on_module_inspected_callback);

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

  ~ModuleInspector() override;

  // Starts the background inspection of modules.
  void StartInspection();

  // Adds the module to the queue of modules to inspect. Starts the inspection
  // process if the |queue_| is empty.
  void AddModule(const ModuleInfoKey& module_key);

  // Returns true if ModuleInspector is not doing anything right now.
  bool IsIdle();

  // ModuleDatabaseObserver:
  void OnModuleDatabaseIdle() override;

  static base::FilePath GetInspectionResultsCachePath();

  // Sets a test factory function to create the UtilWin instance.
  using UtilWinFactoryCallback =
      base::RepeatingCallback<mojo::Remote<chrome::mojom::UtilWin>()>;
  void SetUtilWinFactoryCallbackForTesting(
      UtilWinFactoryCallback util_win_factory_callback);

  int get_connection_error_retry_count_for_testing() const {
    return connection_error_retry_count_;
  }

 private:
  // Ensures the |remote_util_win_| instance is bound to the UtilWin service.
  void EnsureUtilWinServiceBound();

  // Invoked when the InspectionResultsCache is available.
  void OnInspectionResultsCacheRead(
      InspectionResultsCache inspection_results_cache);

  // Handles a connection error to the UtilWin service.
  void OnUtilWinServiceConnectionError();

  // Starts inspecting the module at the front of the queue.
  void StartInspectingModule();

  // Adds the newly inspected module to the cache then calls
  // OnInspectionFinished().
  void OnModuleNewlyInspected(const ModuleInfoKey& module_key,
                              ModuleInspectionResult inspection_result);

  // Called back on the execution context on which the ModuleInspector was
  // created when a module has finished being inspected. The callback will be
  // executed and, if the |queue_| is not empty, the next module will be sent
  // for inspection.
  void OnInspectionFinished(const ModuleInfoKey& module_key,
                            ModuleInspectionResult inspection_result);

  // Sends a task on a blocking background sequence to serialize
  // |inspection_results_cache_|, should it be needed.
  void MaybeUpdateInspectionResultsCache();

  OnModuleInspectedCallback on_module_inspected_callback_;

  // The modules are put in queue until they are sent for inspection.
  base::queue<ModuleInfoKey> queue_;

  // Indicates inspection was started. Used to delay the background inspection
  // tasks until the results have been requested (by calling StartInspection()).
  bool is_started_;

  // A callback used to initialize |remote_util_win_|.
  UtilWinFactoryCallback util_win_factory_callback_;

  // A remote interface to the UtilWin service. It is created when inspection is
  // ongoing, and freed when no longer needed.
  mojo::Remote<chrome::mojom::UtilWin> remote_util_win_;

  // The vector of paths to %env_var%, used to account for differences in
  // localization and where people keep their files.
  // e.g. c:\windows vs d:\windows
  StringMapping path_mapping_;

  // This task runner handles updates to the inspection results cache.
  scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;

  // Indicates if the inspection results cache was read from disk.
  bool inspection_results_cache_read_;

  // Contains the cached inspection results so that a module is not inspected
  // more than once between restarts.
  InspectionResultsCache inspection_results_cache_;

  // Ensures that newly inspected modules are flushed to the disk after at most
  // 5 minutes to avoid losing too much of the work done if the browser is
  // closed before all modules are inspected.
  base::RetainingOneShotTimer flush_inspection_results_timer_;

  // Indicates if a module was newly inspected and the cache must be updated.
  bool has_new_inspection_results_;

  // The number of time this class will try to restart the UtilWin service if a
  // connection error occurs. This is to prevent the degenerate case where the
  // service always fails to start and the restart cycle happens infinitely.
  int connection_error_retry_count_;

  // Indicates if a module is currently being inspected asynchronously by the
  // UtilWin service.
  bool is_waiting_on_util_win_service_;

  SEQUENCE_CHECKER(sequence_checker_);

  // Weak pointers are used to safely post the inspection result back to the
  // ModuleInspector from the task scheduler.
  base::WeakPtrFactory<ModuleInspector> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_WIN_CONFLICTS_MODULE_INSPECTOR_H_