• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
7 #include <stddef.h>
8 
9 #include <vector>
10 
11 #include "base/bind.h"
12 #include "base/lazy_instance.h"
13 #include "base/location.h"
14 #include "base/macros.h"
15 #include "base/threading/thread_checker.h"
16 
17 namespace base {
18 namespace {
19 
20 LazyInstance<std::vector<ActionCallback>> g_callbacks =
21     LAZY_INSTANCE_INITIALIZER;
22 LazyInstance<scoped_refptr<SingleThreadTaskRunner>> g_task_runner =
23     LAZY_INSTANCE_INITIALIZER;
24 
25 }  // namespace
26 
RecordAction(const UserMetricsAction & action)27 void RecordAction(const UserMetricsAction& action) {
28   RecordComputedAction(action.str_);
29 }
30 
RecordComputedAction(const std::string & action)31 void RecordComputedAction(const std::string& action) {
32   if (!g_task_runner.Get()) {
33     DCHECK(g_callbacks.Get().empty());
34     return;
35   }
36 
37   if (!g_task_runner.Get()->BelongsToCurrentThread()) {
38     g_task_runner.Get()->PostTask(FROM_HERE,
39                                   Bind(&RecordComputedAction, action));
40     return;
41   }
42 
43   for (const ActionCallback& callback : g_callbacks.Get()) {
44     callback.Run(action);
45   }
46 }
47 
AddActionCallback(const ActionCallback & callback)48 void AddActionCallback(const ActionCallback& callback) {
49   // Only allow adding a callback if the task runner is set.
50   DCHECK(g_task_runner.Get());
51   DCHECK(g_task_runner.Get()->BelongsToCurrentThread());
52   g_callbacks.Get().push_back(callback);
53 }
54 
RemoveActionCallback(const ActionCallback & callback)55 void RemoveActionCallback(const ActionCallback& callback) {
56   DCHECK(g_task_runner.Get());
57   DCHECK(g_task_runner.Get()->BelongsToCurrentThread());
58   std::vector<ActionCallback>* callbacks = g_callbacks.Pointer();
59   for (size_t i = 0; i < callbacks->size(); ++i) {
60     if ((*callbacks)[i].Equals(callback)) {
61       callbacks->erase(callbacks->begin() + i);
62       return;
63     }
64   }
65 }
66 
SetRecordActionTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner)67 void SetRecordActionTaskRunner(
68     scoped_refptr<SingleThreadTaskRunner> task_runner) {
69   DCHECK(task_runner->BelongsToCurrentThread());
70   DCHECK(!g_task_runner.Get() || g_task_runner.Get()->BelongsToCurrentThread());
71   g_task_runner.Get() = task_runner;
72 }
73 
74 }  // namespace base
75