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)27void RecordAction(const UserMetricsAction& action) { 28 RecordComputedAction(action.str_); 29 } 30 RecordComputedAction(const std::string & action)31void 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)48void 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)55void 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)67void 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