blob: cb55bfc28d3895ddcb404cf01970422ed5b2f94d [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2014 The Chromium Authors
[email protected]e6e30ac2014-01-13 21:24:392// 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
avi9b6f42932015-12-26 22:15:147#include <stddef.h>
8
[email protected]e6e30ac2014-01-13 21:24:399#include <vector>
10
Avi Drissman63e1f992023-01-13 18:54:4311#include "base/functional/bind.h"
[email protected]e6e30ac2014-01-13 21:24:3912#include "base/lazy_instance.h"
beaudoind5c435e2016-04-22 14:17:1013#include "base/location.h"
Peter Kastingfea6bb72022-09-29 16:41:2414#include "base/ranges/algorithm.h"
[email protected]abca0982014-04-10 01:12:3615#include "base/threading/thread_checker.h"
bttkc8a31b702020-02-25 02:55:1716#include "base/time/time.h"
Eric Secklerf6c544f2020-06-02 10:49:2117#include "base/trace_event/base_tracing.h"
[email protected]e6e30ac2014-01-13 21:24:3918
19namespace base {
20namespace {
21
scottmg5e65e3a2017-03-08 08:48:4622LazyInstance<std::vector<ActionCallback>>::DestructorAtExit g_callbacks =
beaudoind5c435e2016-04-22 14:17:1023 LAZY_INSTANCE_INITIALIZER;
scottmg5e65e3a2017-03-08 08:48:4624LazyInstance<scoped_refptr<SingleThreadTaskRunner>>::DestructorAtExit
25 g_task_runner = LAZY_INSTANCE_INITIALIZER;
[email protected]e6e30ac2014-01-13 21:24:3926
27} // namespace
28
29void RecordAction(const UserMetricsAction& action) {
beaudoind5c435e2016-04-22 14:17:1030 RecordComputedAction(action.str_);
[email protected]e6e30ac2014-01-13 21:24:3931}
32
33void RecordComputedAction(const std::string& action) {
bttkc8a31b702020-02-25 02:55:1734 RecordComputedActionAt(action, TimeTicks::Now());
35}
36
bttk211b8512020-03-18 04:24:0137void RecordComputedActionSince(const std::string& action,
38 TimeDelta time_since) {
39 RecordComputedActionAt(action, TimeTicks::Now() - time_since);
40}
41
bttkc8a31b702020-02-25 02:55:1742void RecordComputedActionAt(const std::string& action, TimeTicks action_time) {
43 TRACE_EVENT_INSTANT1("ui", "UserEvent", TRACE_EVENT_SCOPE_GLOBAL, "action",
44 action);
beaudoind5c435e2016-04-22 14:17:1045 if (!g_task_runner.Get()) {
46 DCHECK(g_callbacks.Get().empty());
47 return;
48 }
49
50 if (!g_task_runner.Get()->BelongsToCurrentThread()) {
bttkc8a31b702020-02-25 02:55:1751 g_task_runner.Get()->PostTask(
52 FROM_HERE, BindOnce(&RecordComputedActionAt, action, action_time));
beaudoind5c435e2016-04-22 14:17:1053 return;
54 }
55
56 for (const ActionCallback& callback : g_callbacks.Get()) {
bttkc8a31b702020-02-25 02:55:1757 callback.Run(action, action_time);
beaudoind5c435e2016-04-22 14:17:1058 }
[email protected]e6e30ac2014-01-13 21:24:3959}
60
61void AddActionCallback(const ActionCallback& callback) {
beaudoind5c435e2016-04-22 14:17:1062 // 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);
[email protected]e6e30ac2014-01-13 21:24:3966}
67
68void RemoveActionCallback(const ActionCallback& callback) {
beaudoind5c435e2016-04-22 14:17:1069 DCHECK(g_task_runner.Get());
70 DCHECK(g_task_runner.Get()->BelongsToCurrentThread());
71 std::vector<ActionCallback>* callbacks = g_callbacks.Pointer();
Peter Kastingfea6bb72022-09-29 16:41:2472 const auto i = ranges::find(*callbacks, callback);
Peter Kastingfc94f5062022-06-08 16:41:4573 if (i != callbacks->end())
74 callbacks->erase(i);
beaudoind5c435e2016-04-22 14:17:1075}
[email protected]abca0982014-04-10 01:12:3676
beaudoind5c435e2016-04-22 14:17:1077void 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;
[email protected]e6e30ac2014-01-13 21:24:3982}
83
ssid70aefba42020-02-04 19:34:0384scoped_refptr<SingleThreadTaskRunner> GetRecordActionTaskRunner() {
85 if (g_task_runner.IsCreated())
86 return g_task_runner.Get();
87 return nullptr;
88}
89
[email protected]e6e30ac2014-01-13 21:24:3990} // namespace base