xref: /aosp_15_r20/external/cronet/base/metrics/user_metrics.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 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 "base/metrics/user_metrics.h"
6 
7 #include <stddef.h>
8 
9 #include <vector>
10 
11 #include "base/functional/bind.h"
12 #include "base/lazy_instance.h"
13 #include "base/location.h"
14 #include "base/ranges/algorithm.h"
15 #include "base/threading/thread_checker.h"
16 #include "base/time/time.h"
17 #include "base/trace_event/base_tracing.h"
18 
19 namespace base {
20 namespace {
21 
22 LazyInstance<std::vector<ActionCallback>>::DestructorAtExit g_callbacks =
23     LAZY_INSTANCE_INITIALIZER;
24 LazyInstance<scoped_refptr<SingleThreadTaskRunner>>::DestructorAtExit
25     g_task_runner = LAZY_INSTANCE_INITIALIZER;
26 
27 }  // namespace
28 
RecordAction(const UserMetricsAction & action)29 void RecordAction(const UserMetricsAction& action) {
30   RecordComputedAction(action.str_);
31 }
32 
RecordComputedAction(const std::string & action)33 void RecordComputedAction(const std::string& action) {
34   RecordComputedActionAt(action, TimeTicks::Now());
35 }
36 
RecordComputedActionSince(const std::string & action,TimeDelta time_since)37 void RecordComputedActionSince(const std::string& action,
38                                TimeDelta time_since) {
39   RecordComputedActionAt(action, TimeTicks::Now() - time_since);
40 }
41 
RecordComputedActionAt(const std::string & action,TimeTicks action_time)42 void RecordComputedActionAt(const std::string& action, TimeTicks action_time) {
43   TRACE_EVENT_INSTANT1("ui", "UserEvent", TRACE_EVENT_SCOPE_GLOBAL, "action",
44                        action);
45   if (!g_task_runner.Get()) {
46     DCHECK(g_callbacks.Get().empty());
47     return;
48   }
49 
50   if (!g_task_runner.Get()->BelongsToCurrentThread()) {
51     g_task_runner.Get()->PostTask(
52         FROM_HERE, BindOnce(&RecordComputedActionAt, action, action_time));
53     return;
54   }
55 
56   for (const ActionCallback& callback : g_callbacks.Get()) {
57     callback.Run(action, action_time);
58   }
59 }
60 
AddActionCallback(const ActionCallback & callback)61 void AddActionCallback(const ActionCallback& callback) {
62   // Only allow adding a callback if the task runner is set.
63   DCHECK(g_task_runner.Get());
64   DCHECK(g_task_runner.Get()->BelongsToCurrentThread());
65   g_callbacks.Get().push_back(callback);
66 }
67 
RemoveActionCallback(const ActionCallback & callback)68 void RemoveActionCallback(const ActionCallback& callback) {
69   DCHECK(g_task_runner.Get());
70   DCHECK(g_task_runner.Get()->BelongsToCurrentThread());
71   std::vector<ActionCallback>* callbacks = g_callbacks.Pointer();
72   const auto i = ranges::find(*callbacks, callback);
73   if (i != callbacks->end())
74     callbacks->erase(i);
75 }
76 
SetRecordActionTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner)77 void SetRecordActionTaskRunner(
78     scoped_refptr<SingleThreadTaskRunner> task_runner) {
79   DCHECK(task_runner->BelongsToCurrentThread());
80   DCHECK(!g_task_runner.Get() || g_task_runner.Get()->BelongsToCurrentThread());
81   g_task_runner.Get() = task_runner;
82 }
83 
GetRecordActionTaskRunner()84 scoped_refptr<SingleThreadTaskRunner> GetRecordActionTaskRunner() {
85   if (g_task_runner.IsCreated())
86     return g_task_runner.Get();
87   return nullptr;
88 }
89 
90 }  // namespace base
91