// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/metrics/user_metrics.h" #include <stddef.h> #include <vector> #include "base/bind.h" #include "base/lazy_instance.h" #include "base/location.h" #include "base/macros.h" #include "base/threading/thread_checker.h" namespace base { namespace { LazyInstance<std::vector<ActionCallback>>::DestructorAtExit g_callbacks = LAZY_INSTANCE_INITIALIZER; LazyInstance<scoped_refptr<SingleThreadTaskRunner>>::DestructorAtExit g_task_runner = LAZY_INSTANCE_INITIALIZER; } // namespace void RecordAction(const UserMetricsAction& action) { RecordComputedAction(action.str_); } void RecordComputedAction(const std::string& action) { if (!g_task_runner.Get()) { DCHECK(g_callbacks.Get().empty()); return; } if (!g_task_runner.Get()->BelongsToCurrentThread()) { g_task_runner.Get()->PostTask(FROM_HERE, BindOnce(&RecordComputedAction, action)); return; } for (const ActionCallback& callback : g_callbacks.Get()) { callback.Run(action); } } void AddActionCallback(const ActionCallback& callback) { // Only allow adding a callback if the task runner is set. DCHECK(g_task_runner.Get()); DCHECK(g_task_runner.Get()->BelongsToCurrentThread()); g_callbacks.Get().push_back(callback); } void RemoveActionCallback(const ActionCallback& callback) { DCHECK(g_task_runner.Get()); DCHECK(g_task_runner.Get()->BelongsToCurrentThread()); std::vector<ActionCallback>* callbacks = g_callbacks.Pointer(); for (size_t i = 0; i < callbacks->size(); ++i) { if ((*callbacks)[i].Equals(callback)) { callbacks->erase(callbacks->begin() + i); return; } } } void SetRecordActionTaskRunner( scoped_refptr<SingleThreadTaskRunner> task_runner) { DCHECK(task_runner->BelongsToCurrentThread()); DCHECK(!g_task_runner.Get() || g_task_runner.Get()->BelongsToCurrentThread()); g_task_runner.Get() = task_runner; } } // namespace base