1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef COMPONENTS_METRICS_HISTOGRAM_CONTROLLER_H_
6 #define COMPONENTS_METRICS_HISTOGRAM_CONTROLLER_H_
7
8 #include <map>
9 #include <string>
10 #include <vector>
11
12 #include "base/component_export.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/memory/singleton.h"
15 #include "base/memory/unsafe_shared_memory_region.h"
16 #include "base/sequence_checker.h"
17 #include "base/timer/timer.h"
18 #include "components/metrics/histogram_child_process.h"
19 #include "components/metrics/public/mojom/histogram_fetcher.mojom.h"
20 #include "mojo/public/cpp/bindings/remote.h"
21
22 namespace metrics {
23
24 class HistogramSubscriber;
25
26 // HistogramController is used on the browser process to collect histogram data.
27 // Only one thread (typically the UI thread) is allowed to interact with the
28 // HistogramController object.
COMPONENT_EXPORT(METRICS)29 class COMPONENT_EXPORT(METRICS) HistogramController {
30 public:
31 // Returns the HistogramController object for the current process, or null if
32 // none.
33 static HistogramController* GetInstance();
34
35 // Normally instantiated when the child process is launched. Only one instance
36 // should be created per process.
37 HistogramController();
38
39 HistogramController(const HistogramController&) = delete;
40 HistogramController& operator=(const HistogramController&) = delete;
41
42 virtual ~HistogramController();
43
44 // Register the subscriber so that it will be called when for example
45 // OnHistogramDataCollected is returning histogram data from a child process.
46 void Register(HistogramSubscriber* subscriber);
47
48 // Unregister the subscriber so that it will not be called when for example
49 // OnHistogramDataCollected is returning histogram data from a child process.
50 // Safe to call even if caller is not the current subscriber.
51 void Unregister(const HistogramSubscriber* subscriber);
52
53 // Contact all processes and get their histogram data.
54 void GetHistogramData(int sequence_number);
55
56 enum class ChildProcessMode {
57 // This child process should be included when gathering non-persistent
58 // histogram data from child processes.
59 kGetHistogramData,
60
61 // This child process should only be included in pings, but histogram data
62 // should not be collected.
63 kPingOnly,
64 };
65 void SetHistogramMemory(HistogramChildProcess* host,
66 base::UnsafeSharedMemoryRegion shared_region,
67 ChildProcessMode mode);
68
69 // Some hosts can be re-used before Mojo recognizes that their connections
70 // are invalid because the previous child process died.
71 void NotifyChildDied(HistogramChildProcess* host);
72
73 private:
74 friend struct base::LeakySingletonTraits<HistogramController>;
75
76 raw_ptr<HistogramSubscriber> subscriber_;
77
78 void InsertChildHistogramFetcherInterface(
79 HistogramChildProcess* host,
80 mojo::Remote<mojom::ChildHistogramFetcher> child_histogram_fetcher,
81 ChildProcessMode mode);
82
83 // Calls PingChildProcess() on ~10% of child processes. Not all child
84 // processes are pinged so as to avoid possibly "waking up" too many and
85 // causing unnecessary work.
86 void PingChildProcesses();
87
88 // Pings a child process through its |fetcher|. This does nothing except emit
89 // histograms (both on the browser process and the child process), with the
90 // goal of quantifying the amount of histogram samples lost from child
91 // processes.
92 void PingChildProcess(mojom::ChildHistogramFetcherProxy* fetcher,
93 mojom::UmaPingCallSource call_source);
94
95 // Callback for when a child process has received a ping (see
96 // PingChildProcess()).
97 void Pong(mojom::UmaPingCallSource call_source);
98
99 void RemoveChildHistogramFetcherInterface(
100 MayBeDangling<HistogramChildProcess> host);
101
102 // Records the histogram data collected from a child process.
103 void OnHistogramDataCollected(
104 int sequence_number,
105 const std::vector<std::string>& pickled_histograms);
106
107 struct ChildHistogramFetcher;
108 using ChildHistogramFetcherMap =
109 std::map<HistogramChildProcess*, ChildHistogramFetcher>;
110 ChildHistogramFetcherMap child_histogram_fetchers_;
111
112 // Used to call PingAllChildProcesses() every 5 minutes.
113 base::RepeatingTimer timer_;
114
115 SEQUENCE_CHECKER(sequence_checker_);
116 };
117
118 } // namespace metrics
119
120 #endif // COMPONENTS_METRICS_HISTOGRAM_CONTROLLER_H_
121