Add dbghelp.dll that works on XP, and include in base.isolate
[chromium-blink-merge.git] / base / android / record_histogram.cc
blob0df0487ce8eaef337f6f2df2b62a5b4fad005e1a
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/statistics_recorder.h"
14 #include "base/synchronization/lock.h"
15 #include "base/time/time.h"
16 #include "jni/RecordHistogram_jni.h"
18 namespace base {
19 namespace android {
20 namespace {
22 // Simple thread-safe wrapper for caching histograms. This avoids
23 // relatively expensive JNI string translation for each recording.
24 class HistogramCache {
25 public:
26 HistogramCache() {}
28 HistogramBase* BooleanHistogram(JNIEnv* env,
29 jstring j_histogram_name,
30 jint j_histogram_key) {
31 DCHECK(j_histogram_name);
32 DCHECK(j_histogram_key);
33 HistogramBase* histogram = FindLocked(j_histogram_key);
34 if (histogram)
35 return histogram;
37 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
38 histogram = BooleanHistogram::FactoryGet(
39 histogram_name, HistogramBase::kUmaTargetedHistogramFlag);
40 return InsertLocked(j_histogram_key, histogram);
43 HistogramBase* EnumeratedHistogram(JNIEnv* env,
44 jstring j_histogram_name,
45 jint j_histogram_key,
46 jint j_boundary) {
47 DCHECK(j_histogram_name);
48 DCHECK(j_histogram_key);
49 HistogramBase* histogram = FindLocked(j_histogram_key);
50 int boundary = static_cast<int>(j_boundary);
51 if (histogram) {
52 DCHECK(histogram->HasConstructionArguments(1, boundary, boundary + 1));
53 return histogram;
56 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
57 histogram =
58 LinearHistogram::FactoryGet(histogram_name, 1, boundary, boundary + 1,
59 HistogramBase::kUmaTargetedHistogramFlag);
60 return InsertLocked(j_histogram_key, histogram);
63 HistogramBase* CustomTimesHistogram(JNIEnv* env,
64 jstring j_histogram_name,
65 jint j_histogram_key,
66 jlong j_min,
67 jlong j_max,
68 jint j_bucket_count) {
69 DCHECK(j_histogram_name);
70 DCHECK(j_histogram_key);
71 HistogramBase* histogram = FindLocked(j_histogram_key);
72 int64 min = static_cast<int64>(j_min);
73 int64 max = static_cast<int64>(j_max);
74 int bucket_count = static_cast<int>(j_bucket_count);
75 if (histogram) {
76 DCHECK(histogram->HasConstructionArguments(min, max, bucket_count));
77 return histogram;
80 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
81 // This intentionally uses FactoryGet and not FactoryTimeGet. FactoryTimeGet
82 // is just a convenience for constructing the underlying Histogram with
83 // TimeDelta arguments.
84 histogram = Histogram::FactoryGet(histogram_name, min, max, bucket_count,
85 HistogramBase::kUmaTargetedHistogramFlag);
86 return InsertLocked(j_histogram_key, histogram);
89 private:
90 HistogramBase* FindLocked(jint j_histogram_key) {
91 base::AutoLock locked(lock_);
92 auto histogram_it = histograms_.find(j_histogram_key);
93 return histogram_it != histograms_.end() ? histogram_it->second : nullptr;
96 HistogramBase* InsertLocked(jint j_histogram_key, HistogramBase* histogram) {
97 base::AutoLock locked(lock_);
98 histograms_.insert(std::make_pair(j_histogram_key, histogram));
99 return histogram;
102 base::Lock lock_;
103 std::map<jint, HistogramBase*> histograms_;
105 DISALLOW_COPY_AND_ASSIGN(HistogramCache);
108 base::LazyInstance<HistogramCache>::Leaky g_histograms;
110 } // namespace
112 void RecordBooleanHistogram(JNIEnv* env,
113 jclass clazz,
114 jstring j_histogram_name,
115 jint j_histogram_key,
116 jboolean j_sample) {
117 bool sample = static_cast<bool>(j_sample);
118 g_histograms.Get()
119 .BooleanHistogram(env, j_histogram_name, j_histogram_key)
120 ->AddBoolean(sample);
123 void RecordEnumeratedHistogram(JNIEnv* env,
124 jclass clazz,
125 jstring j_histogram_name,
126 jint j_histogram_key,
127 jint j_sample,
128 jint j_boundary) {
129 int sample = static_cast<int>(j_sample);
131 g_histograms.Get()
132 .EnumeratedHistogram(env, j_histogram_name, j_histogram_key, j_boundary)
133 ->Add(sample);
136 void RecordCustomTimesHistogramMilliseconds(JNIEnv* env,
137 jclass clazz,
138 jstring j_histogram_name,
139 jint j_histogram_key,
140 jlong j_duration,
141 jlong j_min,
142 jlong j_max,
143 jint j_num_buckets) {
144 g_histograms.Get()
145 .CustomTimesHistogram(env, j_histogram_name, j_histogram_key, j_min,
146 j_max, j_num_buckets)
147 ->AddTime(TimeDelta::FromMilliseconds(static_cast<int64>(j_duration)));
150 void Initialize(JNIEnv* env, jclass) {
151 StatisticsRecorder::Initialize();
154 // This backs a Java test util for testing histograms -
155 // MetricsUtils.HistogramDelta. It should live in a test-specific file, but we
156 // currently can't have test-specific native code packaged in test-specific Java
157 // targets - see http://crbug.com/415945.
158 jint GetHistogramValueCountForTesting(JNIEnv* env,
159 jclass clazz,
160 jstring histogram_name,
161 jint sample) {
162 HistogramBase* histogram = StatisticsRecorder::FindHistogram(
163 android::ConvertJavaStringToUTF8(env, histogram_name));
164 if (histogram == nullptr) {
165 // No samples have been recorded for this histogram (yet?).
166 return 0;
169 scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
170 return samples->GetCount(static_cast<int>(sample));
173 bool RegisterRecordHistogram(JNIEnv* env) {
174 return RegisterNativesImpl(env);
177 } // namespace android
178 } // namespace base