xref: /aosp_15_r20/external/cronet/components/metrics/child_histogram_fetcher_impl.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #include "components/metrics/child_histogram_fetcher_impl.h"
6 
7 #include <memory>
8 
9 #include "base/functional/bind.h"
10 #include "base/location.h"
11 #include "base/metrics/histogram_delta_serialization.h"
12 #include "base/metrics/histogram_functions.h"
13 #include "base/metrics/histogram_macros.h"
14 #include "base/metrics/histogram_macros_local.h"
15 #include "base/metrics/persistent_histogram_allocator.h"
16 #include "components/metrics/public/mojom/histogram_fetcher.mojom.h"
17 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
18 #include "mojo/public/cpp/system/platform_handle.h"
19 
20 namespace metrics {
21 
22 ChildHistogramFetcherFactoryImpl::ChildHistogramFetcherFactoryImpl() = default;
23 
24 ChildHistogramFetcherFactoryImpl::~ChildHistogramFetcherFactoryImpl() = default;
25 
Create(mojo::PendingReceiver<mojom::ChildHistogramFetcherFactory> receiver)26 void ChildHistogramFetcherFactoryImpl::Create(
27     mojo::PendingReceiver<mojom::ChildHistogramFetcherFactory> receiver) {
28   mojo::MakeSelfOwnedReceiver(
29       std::make_unique<ChildHistogramFetcherFactoryImpl>(),
30       std::move(receiver));
31 }
32 
CreateFetcher(base::UnsafeSharedMemoryRegion shared_memory,mojo::PendingReceiver<mojom::ChildHistogramFetcher> receiver)33 void ChildHistogramFetcherFactoryImpl::CreateFetcher(
34     base::UnsafeSharedMemoryRegion shared_memory,
35     mojo::PendingReceiver<mojom::ChildHistogramFetcher> receiver) {
36   // This message must be received only once.
37   static bool already_called = false;
38   CHECK(!already_called);
39   already_called = true;
40 
41   // If the shared memory region was passed via the command line, then the
42   // global histogram allocator should already by setup. Otherwise, the region
43   // is being passed via this IPC. We need to initialize the global histogram
44   // allocator and the tracking histograms here.
45   if (shared_memory.IsValid() && !base::GlobalHistogramAllocator::Get()) {
46     base::GlobalHistogramAllocator::CreateWithSharedMemoryRegion(shared_memory);
47     // Emit a local histogram, which should not be reported to servers. This is
48     // monitored from the serverside.
49     LOCAL_HISTOGRAM_BOOLEAN("UMA.LocalHistogram", true);
50 
51     base::PersistentHistogramAllocator* global_allocator =
52         base::GlobalHistogramAllocator::Get();
53     if (global_allocator) {
54       global_allocator->CreateTrackingHistograms(global_allocator->Name());
55     }
56   }
57 
58   // Setup the Mojo receiver.
59   mojo::MakeSelfOwnedReceiver(std::make_unique<ChildHistogramFetcherImpl>(),
60                               std::move(receiver));
61 }
62 
63 ChildHistogramFetcherImpl::ChildHistogramFetcherImpl() = default;
64 
65 ChildHistogramFetcherImpl::~ChildHistogramFetcherImpl() = default;
66 
67 // Extract snapshot data and then send it off to the Browser process.
68 // Send only a delta to what we have already sent.
GetChildNonPersistentHistogramData(GetChildNonPersistentHistogramDataCallback callback)69 void ChildHistogramFetcherImpl::GetChildNonPersistentHistogramData(
70     GetChildNonPersistentHistogramDataCallback callback) {
71   // If a persistent allocator is in use, it needs to occasionally update
72   // some internal histograms. An upload is happening so this is a good time.
73   base::PersistentHistogramAllocator* global_allocator =
74       base::GlobalHistogramAllocator::Get();
75   if (global_allocator) {
76     global_allocator->UpdateTrackingHistograms();
77   }
78 
79   if (!histogram_delta_serialization_) {
80     histogram_delta_serialization_ =
81         std::make_unique<base::HistogramDeltaSerialization>("ChildProcess");
82   }
83 
84   std::vector<std::string> deltas;
85   // "false" to PerpareAndSerializeDeltas() indicates to *not* include
86   // histograms held in persistent storage on the assumption that they will be
87   // visible to the recipient through other means.
88   histogram_delta_serialization_->PrepareAndSerializeDeltas(&deltas, false);
89 
90   std::move(callback).Run(deltas);
91 
92 #ifndef NDEBUG
93   static int count = 0;
94   count++;
95   LOCAL_HISTOGRAM_COUNTS("Histogram.ChildProcessHistogramSentCount", count);
96 #endif
97 }
98 
Ping(mojom::UmaPingCallSource call_source,PingCallback callback)99 void ChildHistogramFetcherImpl::Ping(mojom::UmaPingCallSource call_source,
100                                      PingCallback callback) {
101   // Since the ChildHistogramFetcherImpl instance was created after setting up
102   // the shared memory (if there was one -- see CreateFetcher()), this histogram
103   // will live in it (i.e., it should have the |kIsPersistent| flag).
104   const char* histogram_name = nullptr;
105   switch (call_source) {
106     case mojom::UmaPingCallSource::PERIODIC:
107       histogram_name = "UMA.ChildProcess.Ping.Periodic";
108       break;
109     case mojom::UmaPingCallSource::SHARED_MEMORY_SET_UP:
110       histogram_name = "UMA.ChildProcess.Ping.SharedMemorySetUp";
111       break;
112   }
113   base::UmaHistogramEnumeration(histogram_name,
114                                 mojom::UmaChildPingStatus::CHILD_RECEIVED_IPC);
115 
116   std::move(callback).Run();
117 }
118 
119 }  // namespace metrics
120