1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/android/record_histogram.h"
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h>
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <map>
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <string>
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/android/jni_android.h"
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/android/jni_string.h"
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/lazy_instance.h"
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/macros.h"
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/metrics/histogram.h"
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/metrics/sparse_histogram.h"
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/metrics/statistics_recorder.h"
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/strings/stringprintf.h"
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/synchronization/lock.h"
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/time/time.h"
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "jni/RecordHistogram_jni.h"
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace base {
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace android {
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace {
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Simple thread-safe wrapper for caching histograms. This avoids
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// relatively expensive JNI string translation for each recording.
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass HistogramCache {
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramCache() {}
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::string HistogramConstructionParamsToString(HistogramBase* histogram) {
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::string params_str = histogram->histogram_name();
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    switch (histogram->GetHistogramType()) {
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      case HISTOGRAM:
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      case LINEAR_HISTOGRAM:
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      case BOOLEAN_HISTOGRAM:
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      case CUSTOM_HISTOGRAM: {
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        Histogram* hist = static_cast<Histogram*>(histogram);
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        params_str += StringPrintf("/%d/%d/%d", hist->declared_min(),
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                   hist->declared_max(), hist->bucket_count());
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        break;
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      }
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      case SPARSE_HISTOGRAM:
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        break;
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return params_str;
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void CheckHistogramArgs(JNIEnv* env,
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                          jstring j_histogram_name,
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                          int32_t expected_min,
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                          int32_t expected_max,
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                          int32_t expected_bucket_count,
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                          HistogramBase* histogram) {
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(histogram->HasConstructionArguments(expected_min, expected_max,
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                               expected_bucket_count))
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        << ConvertJavaStringToUTF8(env, j_histogram_name) << "/" << expected_min
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        << "/" << expected_max << "/" << expected_bucket_count << " vs. "
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        << HistogramConstructionParamsToString(histogram);
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* BooleanHistogram(JNIEnv* env,
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  jstring j_histogram_name,
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  jlong j_histogram_key) {
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(j_histogram_name);
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (histogram)
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      return histogram;
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    histogram = BooleanHistogram::FactoryGet(
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        histogram_name, HistogramBase::kUmaTargetedHistogramFlag);
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return histogram;
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* EnumeratedHistogram(JNIEnv* env,
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                     jstring j_histogram_name,
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                     jlong j_histogram_key,
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                     jint j_boundary) {
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(j_histogram_name);
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t boundary = static_cast<int32_t>(j_boundary);
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (histogram) {
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      CheckHistogramArgs(env, j_histogram_name, 1, boundary, boundary + 1,
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         histogram);
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      return histogram;
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    histogram =
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        LinearHistogram::FactoryGet(histogram_name, 1, boundary, boundary + 1,
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                    HistogramBase::kUmaTargetedHistogramFlag);
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return histogram;
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* CustomCountHistogram(JNIEnv* env,
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jstring j_histogram_name,
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jlong j_histogram_key,
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jint j_min,
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jint j_max,
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jint j_num_buckets) {
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(j_histogram_name);
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t min = static_cast<int32_t>(j_min);
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t max = static_cast<int32_t>(j_max);
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t num_buckets = static_cast<int32_t>(j_num_buckets);
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (histogram) {
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      CheckHistogramArgs(env, j_histogram_name, min, max, num_buckets,
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         histogram);
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      return histogram;
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    histogram =
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        Histogram::FactoryGet(histogram_name, min, max, num_buckets,
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                              HistogramBase::kUmaTargetedHistogramFlag);
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return histogram;
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* LinearCountHistogram(JNIEnv* env,
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jstring j_histogram_name,
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jlong j_histogram_key,
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jint j_min,
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jint j_max,
128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jint j_num_buckets) {
129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(j_histogram_name);
130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t min = static_cast<int32_t>(j_min);
131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t max = static_cast<int32_t>(j_max);
132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t num_buckets = static_cast<int32_t>(j_num_buckets);
133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (histogram) {
135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      CheckHistogramArgs(env, j_histogram_name, min, max, num_buckets,
136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         histogram);
137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      return histogram;
138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    histogram =
142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        LinearHistogram::FactoryGet(histogram_name, min, max, num_buckets,
143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                    HistogramBase::kUmaTargetedHistogramFlag);
144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return histogram;
145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* SparseHistogram(JNIEnv* env,
148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jstring j_histogram_name,
149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jlong j_histogram_key) {
150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(j_histogram_name);
151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (histogram)
153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      return histogram;
154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    histogram = SparseHistogram::FactoryGet(
157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        histogram_name, HistogramBase::kUmaTargetedHistogramFlag);
158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return histogram;
159645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
160645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
161645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* CustomTimesHistogram(JNIEnv* env,
162645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jstring j_histogram_name,
163645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jlong j_histogram_key,
164645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jint j_min,
165645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jint j_max,
166645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      jint j_bucket_count) {
167645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    DCHECK(j_histogram_name);
168645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    HistogramBase* histogram = HistogramFromKey(j_histogram_key);
169645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t min = static_cast<int32_t>(j_min);
170645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t max = static_cast<int32_t>(j_max);
171645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    int32_t bucket_count = static_cast<int32_t>(j_bucket_count);
172645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    if (histogram) {
173645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      CheckHistogramArgs(env, j_histogram_name, min, max, bucket_count,
174645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         histogram);
175645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      return histogram;
176645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
177645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
178645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
179645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // This intentionally uses FactoryGet and not FactoryTimeGet. FactoryTimeGet
180645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // is just a convenience for constructing the underlying Histogram with
181645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // TimeDelta arguments.
182645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    histogram = Histogram::FactoryGet(histogram_name, min, max, bucket_count,
183645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                      HistogramBase::kUmaTargetedHistogramFlag);
184645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return histogram;
185645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
186645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
187645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private:
188645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Convert a jlong |histogram_key| from Java to a HistogramBase* via a cast.
189645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // The Java side caches these in a map (see RecordHistogram.java), which is
190645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // safe to do since C++ Histogram objects are never freed.
191645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static HistogramBase* HistogramFromKey(jlong j_histogram_key) {
192645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return reinterpret_cast<HistogramBase*>(j_histogram_key);
193645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
194645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
195645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DISALLOW_COPY_AND_ASSIGN(HistogramCache);
196645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
197645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
198645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezLazyInstance<HistogramCache>::Leaky g_histograms;
199645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
200645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace
201645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
202645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezjlong RecordBooleanHistogram(JNIEnv* env,
203645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             const JavaParamRef<jclass>& clazz,
204645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             const JavaParamRef<jstring>& j_histogram_name,
205645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             jlong j_histogram_key,
206645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                             jboolean j_sample) {
207645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool sample = static_cast<bool>(j_sample);
208645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* histogram = g_histograms.Get().BooleanHistogram(
209645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      env, j_histogram_name, j_histogram_key);
210645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  histogram->AddBoolean(sample);
211645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return reinterpret_cast<jlong>(histogram);
212645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
213645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
214645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezjlong RecordEnumeratedHistogram(JNIEnv* env,
215645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                const JavaParamRef<jclass>& clazz,
216645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                const JavaParamRef<jstring>& j_histogram_name,
217645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                jlong j_histogram_key,
218645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                jint j_sample,
219645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                jint j_boundary) {
220645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  int sample = static_cast<int>(j_sample);
221645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
222645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* histogram = g_histograms.Get().EnumeratedHistogram(
223645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      env, j_histogram_name, j_histogram_key, j_boundary);
224645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  histogram->Add(sample);
225645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return reinterpret_cast<jlong>(histogram);
226645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
227645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
228645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezjlong RecordCustomCountHistogram(JNIEnv* env,
229645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 const JavaParamRef<jclass>& clazz,
230645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 const JavaParamRef<jstring>& j_histogram_name,
231645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jlong j_histogram_key,
232645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jint j_sample,
233645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jint j_min,
234645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jint j_max,
235645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jint j_num_buckets) {
236645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  int sample = static_cast<int>(j_sample);
237645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
238645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* histogram = g_histograms.Get().CustomCountHistogram(
239645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      env, j_histogram_name, j_histogram_key, j_min, j_max, j_num_buckets);
240645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  histogram->Add(sample);
241645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return reinterpret_cast<jlong>(histogram);
242645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
243645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
244645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezjlong RecordLinearCountHistogram(JNIEnv* env,
245645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 const JavaParamRef<jclass>& clazz,
246645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 const JavaParamRef<jstring>& j_histogram_name,
247645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jlong j_histogram_key,
248645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jint j_sample,
249645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jint j_min,
250645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jint j_max,
251645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 jint j_num_buckets) {
252645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  int sample = static_cast<int>(j_sample);
253645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
254645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* histogram = g_histograms.Get().LinearCountHistogram(
255645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      env, j_histogram_name, j_histogram_key, j_min, j_max, j_num_buckets);
256645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  histogram->Add(sample);
257645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return reinterpret_cast<jlong>(histogram);
258645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
259645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
260645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezjlong RecordSparseHistogram(JNIEnv* env,
261645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                            const JavaParamRef<jclass>& clazz,
262645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                            const JavaParamRef<jstring>& j_histogram_name,
263645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                            jlong j_histogram_key,
264645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                            jint j_sample) {
265645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  int sample = static_cast<int>(j_sample);
266645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* histogram = g_histograms.Get().SparseHistogram(
267645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      env, j_histogram_name, j_histogram_key);
268645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  histogram->Add(sample);
269645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return reinterpret_cast<jlong>(histogram);
270645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
271645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
272645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezjlong RecordCustomTimesHistogramMilliseconds(
273645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    JNIEnv* env,
274645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    const JavaParamRef<jclass>& clazz,
275645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    const JavaParamRef<jstring>& j_histogram_name,
276645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    jlong j_histogram_key,
277645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    jint j_duration,
278645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    jint j_min,
279645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    jint j_max,
280645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    jint j_num_buckets) {
281645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* histogram = g_histograms.Get().CustomTimesHistogram(
282645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      env, j_histogram_name, j_histogram_key, j_min, j_max, j_num_buckets);
283645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  histogram->AddTime(
284645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      TimeDelta::FromMilliseconds(static_cast<int64_t>(j_duration)));
285645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return reinterpret_cast<jlong>(histogram);
286645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
287645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
288645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezvoid Initialize(JNIEnv* env, const JavaParamRef<jclass>&) {
289645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  StatisticsRecorder::Initialize();
290645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
291645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
292645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// This backs a Java test util for testing histograms -
293645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// MetricsUtils.HistogramDelta. It should live in a test-specific file, but we
294645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// currently can't have test-specific native code packaged in test-specific Java
295645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// targets - see http://crbug.com/415945.
296645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezjint GetHistogramValueCountForTesting(
297645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    JNIEnv* env,
298645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    const JavaParamRef<jclass>& clazz,
299645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    const JavaParamRef<jstring>& histogram_name,
300645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    jint sample) {
301645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HistogramBase* histogram = StatisticsRecorder::FindHistogram(
302645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      android::ConvertJavaStringToUTF8(env, histogram_name));
303645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (histogram == nullptr) {
304645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    // No samples have been recorded for this histogram (yet?).
305645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return 0;
306645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  }
307645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
308645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
309645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return samples->GetCount(static_cast<int>(sample));
310645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
311645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
312645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezbool RegisterRecordHistogram(JNIEnv* env) {
313645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return RegisterNativesImpl(env);
314645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
315645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
316645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace android
317645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace base
318