blob: 96183ac45e5c7159373a35f45ede1140807d4a2f [file] [log] [blame]
[email protected]e6e30ac2014-01-13 21:24:391// Copyright 2014 The Chromium Authors. All rights reserved.
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
avi9b6f42932015-12-26 22:15:147#include <stddef.h>
8
[email protected]e6e30ac2014-01-13 21:24:399#include <vector>
10
beaudoind5c435e2016-04-22 14:17:1011#include "base/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"
avi9b6f42932015-12-26 22:15:1414#include "base/macros.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"
Etienne Bergeronc87cdc982018-11-14 18:17:2917#include "base/trace_event/trace_event.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
37void RecordComputedActionAt(const std::string& action, TimeTicks action_time) {
38 TRACE_EVENT_INSTANT1("ui", "UserEvent", TRACE_EVENT_SCOPE_GLOBAL, "action",
39 action);
beaudoind5c435e2016-04-22 14:17:1040 if (!g_task_runner.Get()) {
41 DCHECK(g_callbacks.Get().empty());
42 return;
43 }
44
45 if (!g_task_runner.Get()->BelongsToCurrentThread()) {
bttkc8a31b702020-02-25 02:55:1746 g_task_runner.Get()->PostTask(
47 FROM_HERE, BindOnce(&RecordComputedActionAt, action, action_time));
beaudoind5c435e2016-04-22 14:17:1048 return;
49 }
50
51 for (const ActionCallback& callback : g_callbacks.Get()) {
bttkc8a31b702020-02-25 02:55:1752 callback.Run(action, action_time);
beaudoind5c435e2016-04-22 14:17:1053 }
[email protected]e6e30ac2014-01-13 21:24:3954}
55
56void AddActionCallback(const ActionCallback& callback) {
beaudoind5c435e2016-04-22 14:17:1057 // Only allow adding a callback if the task runner is set.
58 DCHECK(g_task_runner.Get());
59 DCHECK(g_task_runner.Get()->BelongsToCurrentThread());
60 g_callbacks.Get().push_back(callback);
[email protected]e6e30ac2014-01-13 21:24:3961}
62
63void RemoveActionCallback(const ActionCallback& callback) {
beaudoind5c435e2016-04-22 14:17:1064 DCHECK(g_task_runner.Get());
65 DCHECK(g_task_runner.Get()->BelongsToCurrentThread());
66 std::vector<ActionCallback>* callbacks = g_callbacks.Pointer();
67 for (size_t i = 0; i < callbacks->size(); ++i) {
Robert Liao4e4c9b52019-03-11 23:37:4568 if ((*callbacks)[i] == callback) {
beaudoind5c435e2016-04-22 14:17:1069 callbacks->erase(callbacks->begin() + i);
70 return;
71 }
72 }
73}
[email protected]abca0982014-04-10 01:12:3674
beaudoind5c435e2016-04-22 14:17:1075void SetRecordActionTaskRunner(
76 scoped_refptr<SingleThreadTaskRunner> task_runner) {
77 DCHECK(task_runner->BelongsToCurrentThread());
78 DCHECK(!g_task_runner.Get() || g_task_runner.Get()->BelongsToCurrentThread());
79 g_task_runner.Get() = task_runner;
[email protected]e6e30ac2014-01-13 21:24:3980}
81
ssid70aefba42020-02-04 19:34:0382scoped_refptr<SingleThreadTaskRunner> GetRecordActionTaskRunner() {
83 if (g_task_runner.IsCreated())
84 return g_task_runner.Get();
85 return nullptr;
86}
87
[email protected]e6e30ac2014-01-13 21:24:3988} // namespace base