1*635a8641SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #include "base/metrics/user_metrics.h" 6*635a8641SAndroid Build Coastguard Worker 7*635a8641SAndroid Build Coastguard Worker #include <stddef.h> 8*635a8641SAndroid Build Coastguard Worker 9*635a8641SAndroid Build Coastguard Worker #include <vector> 10*635a8641SAndroid Build Coastguard Worker 11*635a8641SAndroid Build Coastguard Worker #include "base/bind.h" 12*635a8641SAndroid Build Coastguard Worker #include "base/lazy_instance.h" 13*635a8641SAndroid Build Coastguard Worker #include "base/location.h" 14*635a8641SAndroid Build Coastguard Worker #include "base/macros.h" 15*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_checker.h" 16*635a8641SAndroid Build Coastguard Worker 17*635a8641SAndroid Build Coastguard Worker namespace base { 18*635a8641SAndroid Build Coastguard Worker namespace { 19*635a8641SAndroid Build Coastguard Worker 20*635a8641SAndroid Build Coastguard Worker LazyInstance<std::vector<ActionCallback>>::DestructorAtExit g_callbacks = 21*635a8641SAndroid Build Coastguard Worker LAZY_INSTANCE_INITIALIZER; 22*635a8641SAndroid Build Coastguard Worker LazyInstance<scoped_refptr<SingleThreadTaskRunner>>::DestructorAtExit 23*635a8641SAndroid Build Coastguard Worker g_task_runner = LAZY_INSTANCE_INITIALIZER; 24*635a8641SAndroid Build Coastguard Worker 25*635a8641SAndroid Build Coastguard Worker } // namespace 26*635a8641SAndroid Build Coastguard Worker RecordAction(const UserMetricsAction & action)27*635a8641SAndroid Build Coastguard Workervoid RecordAction(const UserMetricsAction& action) { 28*635a8641SAndroid Build Coastguard Worker RecordComputedAction(action.str_); 29*635a8641SAndroid Build Coastguard Worker } 30*635a8641SAndroid Build Coastguard Worker RecordComputedAction(const std::string & action)31*635a8641SAndroid Build Coastguard Workervoid RecordComputedAction(const std::string& action) { 32*635a8641SAndroid Build Coastguard Worker if (!g_task_runner.Get()) { 33*635a8641SAndroid Build Coastguard Worker DCHECK(g_callbacks.Get().empty()); 34*635a8641SAndroid Build Coastguard Worker return; 35*635a8641SAndroid Build Coastguard Worker } 36*635a8641SAndroid Build Coastguard Worker 37*635a8641SAndroid Build Coastguard Worker if (!g_task_runner.Get()->BelongsToCurrentThread()) { 38*635a8641SAndroid Build Coastguard Worker g_task_runner.Get()->PostTask(FROM_HERE, 39*635a8641SAndroid Build Coastguard Worker BindOnce(&RecordComputedAction, action)); 40*635a8641SAndroid Build Coastguard Worker return; 41*635a8641SAndroid Build Coastguard Worker } 42*635a8641SAndroid Build Coastguard Worker 43*635a8641SAndroid Build Coastguard Worker for (const ActionCallback& callback : g_callbacks.Get()) { 44*635a8641SAndroid Build Coastguard Worker callback.Run(action); 45*635a8641SAndroid Build Coastguard Worker } 46*635a8641SAndroid Build Coastguard Worker } 47*635a8641SAndroid Build Coastguard Worker AddActionCallback(const ActionCallback & callback)48*635a8641SAndroid Build Coastguard Workervoid AddActionCallback(const ActionCallback& callback) { 49*635a8641SAndroid Build Coastguard Worker // Only allow adding a callback if the task runner is set. 50*635a8641SAndroid Build Coastguard Worker DCHECK(g_task_runner.Get()); 51*635a8641SAndroid Build Coastguard Worker DCHECK(g_task_runner.Get()->BelongsToCurrentThread()); 52*635a8641SAndroid Build Coastguard Worker g_callbacks.Get().push_back(callback); 53*635a8641SAndroid Build Coastguard Worker } 54*635a8641SAndroid Build Coastguard Worker RemoveActionCallback(const ActionCallback & callback)55*635a8641SAndroid Build Coastguard Workervoid RemoveActionCallback(const ActionCallback& callback) { 56*635a8641SAndroid Build Coastguard Worker DCHECK(g_task_runner.Get()); 57*635a8641SAndroid Build Coastguard Worker DCHECK(g_task_runner.Get()->BelongsToCurrentThread()); 58*635a8641SAndroid Build Coastguard Worker std::vector<ActionCallback>* callbacks = g_callbacks.Pointer(); 59*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < callbacks->size(); ++i) { 60*635a8641SAndroid Build Coastguard Worker if ((*callbacks)[i].Equals(callback)) { 61*635a8641SAndroid Build Coastguard Worker callbacks->erase(callbacks->begin() + i); 62*635a8641SAndroid Build Coastguard Worker return; 63*635a8641SAndroid Build Coastguard Worker } 64*635a8641SAndroid Build Coastguard Worker } 65*635a8641SAndroid Build Coastguard Worker } 66*635a8641SAndroid Build Coastguard Worker SetRecordActionTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner)67*635a8641SAndroid Build Coastguard Workervoid SetRecordActionTaskRunner( 68*635a8641SAndroid Build Coastguard Worker scoped_refptr<SingleThreadTaskRunner> task_runner) { 69*635a8641SAndroid Build Coastguard Worker DCHECK(task_runner->BelongsToCurrentThread()); 70*635a8641SAndroid Build Coastguard Worker DCHECK(!g_task_runner.Get() || g_task_runner.Get()->BelongsToCurrentThread()); 71*635a8641SAndroid Build Coastguard Worker g_task_runner.Get() = task_runner; 72*635a8641SAndroid Build Coastguard Worker } 73*635a8641SAndroid Build Coastguard Worker 74*635a8641SAndroid Build Coastguard Worker } // namespace base 75