[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / base / android / record_histogram.cc
blob51ca482e291b9c451331be9442c25239e21aaea4
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.
5 #include "base/android/record_histogram.h"
7 #include <map>
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h"
11 #include "base/lazy_instance.h"
12 #include "base/metrics/histogram.h"
13 #include "base/metrics/sparse_histogram.h"
14 #include "base/metrics/statistics_recorder.h"
15 #include "base/synchronization/lock.h"
16 #include "base/time/time.h"
17 #include "jni/RecordHistogram_jni.h"
19 namespace base {
20 namespace android {
21 namespace {
23 // Simple thread-safe wrapper for caching histograms. This avoids
24 // relatively expensive JNI string translation for each recording.
25 class HistogramCache {
26 public:
27 HistogramCache() {}
29 HistogramBase* BooleanHistogram(JNIEnv* env,
30 jstring j_histogram_name,
31 jint j_histogram_key) {
32 DCHECK(j_histogram_name);
33 DCHECK(j_histogram_key);
34 HistogramBase* histogram = FindLocked(j_histogram_key);
35 if (histogram)
36 return histogram;
38 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
39 histogram = BooleanHistogram::FactoryGet(
40 histogram_name, HistogramBase::kUmaTargetedHistogramFlag);
41 return InsertLocked(j_histogram_key, histogram);
44 HistogramBase* EnumeratedHistogram(JNIEnv* env,
45 jstring j_histogram_name,
46 jint j_histogram_key,
47 jint j_boundary) {
48 DCHECK(j_histogram_name);
49 DCHECK(j_histogram_key);
50 HistogramBase* histogram = FindLocked(j_histogram_key);
51 int boundary = static_cast<int>(j_boundary);
52 if (histogram) {
53 DCHECK(histogram->HasConstructionArguments(1, boundary, boundary + 1));
54 return histogram;
57 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
58 histogram =
59 LinearHistogram::FactoryGet(histogram_name, 1, boundary, boundary + 1,
60 HistogramBase::kUmaTargetedHistogramFlag);
61 return InsertLocked(j_histogram_key, histogram);
64 HistogramBase* CustomCountHistogram(JNIEnv* env,
65 jstring j_histogram_name,
66 jint j_histogram_key,
67 jint j_min,
68 jint j_max,
69 jint j_num_buckets) {
70 DCHECK(j_histogram_name);
71 DCHECK(j_histogram_key);
72 int64 min = static_cast<int64>(j_min);
73 int64 max = static_cast<int64>(j_max);
74 int num_buckets = static_cast<int>(j_num_buckets);
75 HistogramBase* histogram = FindLocked(j_histogram_key);
76 if (histogram) {
77 DCHECK(histogram->HasConstructionArguments(min, max, num_buckets));
78 return histogram;
81 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
82 histogram =
83 Histogram::FactoryGet(histogram_name, min, max, num_buckets,
84 HistogramBase::kUmaTargetedHistogramFlag);
85 return InsertLocked(j_histogram_key, histogram);
88 HistogramBase* LinearCountHistogram(JNIEnv* env,
89 jstring j_histogram_name,
90 jint j_histogram_key,
91 jint j_min,
92 jint j_max,
93 jint j_num_buckets) {
94 DCHECK(j_histogram_name);
95 DCHECK(j_histogram_key);
96 int64 min = static_cast<int64>(j_min);
97 int64 max = static_cast<int64>(j_max);
98 int num_buckets = static_cast<int>(j_num_buckets);
99 HistogramBase* histogram = FindLocked(j_histogram_key);
100 if (histogram) {
101 DCHECK(histogram->HasConstructionArguments(min, max, num_buckets));
102 return histogram;
105 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
106 histogram =
107 LinearHistogram::FactoryGet(histogram_name, min, max, num_buckets,
108 HistogramBase::kUmaTargetedHistogramFlag);
109 return InsertLocked(j_histogram_key, histogram);
112 HistogramBase* SparseHistogram(JNIEnv* env,
113 jstring j_histogram_name,
114 jint j_histogram_key) {
115 DCHECK(j_histogram_name);
116 DCHECK(j_histogram_key);
117 HistogramBase* histogram = FindLocked(j_histogram_key);
118 if (histogram)
119 return histogram;
121 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
122 histogram = SparseHistogram::FactoryGet(
123 histogram_name, HistogramBase::kUmaTargetedHistogramFlag);
124 return InsertLocked(j_histogram_key, histogram);
127 HistogramBase* CustomTimesHistogram(JNIEnv* env,
128 jstring j_histogram_name,
129 jint j_histogram_key,
130 jlong j_min,
131 jlong j_max,
132 jint j_bucket_count) {
133 DCHECK(j_histogram_name);
134 DCHECK(j_histogram_key);
135 HistogramBase* histogram = FindLocked(j_histogram_key);
136 int64 min = static_cast<int64>(j_min);
137 int64 max = static_cast<int64>(j_max);
138 int bucket_count = static_cast<int>(j_bucket_count);
139 if (histogram) {
140 DCHECK(histogram->HasConstructionArguments(min, max, bucket_count));
141 return histogram;
144 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
145 // This intentionally uses FactoryGet and not FactoryTimeGet. FactoryTimeGet
146 // is just a convenience for constructing the underlying Histogram with
147 // TimeDelta arguments.
148 histogram = Histogram::FactoryGet(histogram_name, min, max, bucket_count,
149 HistogramBase::kUmaTargetedHistogramFlag);
150 return InsertLocked(j_histogram_key, histogram);
153 private:
154 HistogramBase* FindLocked(jint j_histogram_key) {
155 base::AutoLock locked(lock_);
156 auto histogram_it = histograms_.find(j_histogram_key);
157 return histogram_it != histograms_.end() ? histogram_it->second : nullptr;
160 HistogramBase* InsertLocked(jint j_histogram_key, HistogramBase* histogram) {
161 base::AutoLock locked(lock_);
162 histograms_.insert(std::make_pair(j_histogram_key, histogram));
163 return histogram;
166 base::Lock lock_;
167 std::map<jint, HistogramBase*> histograms_;
169 DISALLOW_COPY_AND_ASSIGN(HistogramCache);
172 base::LazyInstance<HistogramCache>::Leaky g_histograms;
174 } // namespace
176 void RecordBooleanHistogram(JNIEnv* env,
177 const JavaParamRef<jclass>& clazz,
178 const JavaParamRef<jstring>& j_histogram_name,
179 jint j_histogram_key,
180 jboolean j_sample) {
181 bool sample = static_cast<bool>(j_sample);
182 g_histograms.Get()
183 .BooleanHistogram(env, j_histogram_name, j_histogram_key)
184 ->AddBoolean(sample);
187 void RecordEnumeratedHistogram(JNIEnv* env,
188 const JavaParamRef<jclass>& clazz,
189 const JavaParamRef<jstring>& j_histogram_name,
190 jint j_histogram_key,
191 jint j_sample,
192 jint j_boundary) {
193 int sample = static_cast<int>(j_sample);
195 g_histograms.Get()
196 .EnumeratedHistogram(env, j_histogram_name, j_histogram_key, j_boundary)
197 ->Add(sample);
200 void RecordCustomCountHistogram(JNIEnv* env,
201 const JavaParamRef<jclass>& clazz,
202 const JavaParamRef<jstring>& j_histogram_name,
203 jint j_histogram_key,
204 jint j_sample,
205 jint j_min,
206 jint j_max,
207 jint j_num_buckets) {
208 int sample = static_cast<int>(j_sample);
210 g_histograms.Get()
211 .CustomCountHistogram(env, j_histogram_name, j_histogram_key, j_min,
212 j_max, j_num_buckets)
213 ->Add(sample);
216 void RecordLinearCountHistogram(JNIEnv* env,
217 const JavaParamRef<jclass>& clazz,
218 const JavaParamRef<jstring>& j_histogram_name,
219 jint j_histogram_key,
220 jint j_sample,
221 jint j_min,
222 jint j_max,
223 jint j_num_buckets) {
224 int sample = static_cast<int>(j_sample);
226 g_histograms.Get()
227 .LinearCountHistogram(env, j_histogram_name, j_histogram_key, j_min,
228 j_max, j_num_buckets)
229 ->Add(sample);
232 void RecordSparseHistogram(JNIEnv* env,
233 const JavaParamRef<jclass>& clazz,
234 const JavaParamRef<jstring>& j_histogram_name,
235 jint j_histogram_key,
236 jint j_sample) {
237 int sample = static_cast<int>(j_sample);
238 g_histograms.Get()
239 .SparseHistogram(env, j_histogram_name, j_histogram_key)
240 ->Add(sample);
243 void RecordCustomTimesHistogramMilliseconds(
244 JNIEnv* env,
245 const JavaParamRef<jclass>& clazz,
246 const JavaParamRef<jstring>& j_histogram_name,
247 jint j_histogram_key,
248 jlong j_duration,
249 jlong j_min,
250 jlong j_max,
251 jint j_num_buckets) {
252 g_histograms.Get()
253 .CustomTimesHistogram(env, j_histogram_name, j_histogram_key, j_min,
254 j_max, j_num_buckets)
255 ->AddTime(TimeDelta::FromMilliseconds(static_cast<int64>(j_duration)));
258 void Initialize(JNIEnv* env, const JavaParamRef<jclass>&) {
259 StatisticsRecorder::Initialize();
262 // This backs a Java test util for testing histograms -
263 // MetricsUtils.HistogramDelta. It should live in a test-specific file, but we
264 // currently can't have test-specific native code packaged in test-specific Java
265 // targets - see http://crbug.com/415945.
266 jint GetHistogramValueCountForTesting(
267 JNIEnv* env,
268 const JavaParamRef<jclass>& clazz,
269 const JavaParamRef<jstring>& histogram_name,
270 jint sample) {
271 HistogramBase* histogram = StatisticsRecorder::FindHistogram(
272 android::ConvertJavaStringToUTF8(env, histogram_name));
273 if (histogram == nullptr) {
274 // No samples have been recorded for this histogram (yet?).
275 return 0;
278 scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
279 return samples->GetCount(static_cast<int>(sample));
282 bool RegisterRecordHistogram(JNIEnv* env) {
283 return RegisterNativesImpl(env);
286 } // namespace android
287 } // namespace base