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