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