Home | History | Annotate | Download | only in metrics
      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>>::DestructorAtExit g_callbacks =
     21     LAZY_INSTANCE_INITIALIZER;
     22 LazyInstance<scoped_refptr<SingleThreadTaskRunner>>::DestructorAtExit
     23     g_task_runner = LAZY_INSTANCE_INITIALIZER;
     24 
     25 }  // namespace
     26 
     27 void RecordAction(const UserMetricsAction& action) {
     28   RecordComputedAction(action.str_);
     29 }
     30 
     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 
     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 
     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 
     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