Disable Enhanced Bookmark for ICS devices
[chromium-blink-merge.git] / base / android / record_histogram.cc
blob8b7f7bd1d96df21b94b6d36d705dc0647735a071
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* CountHistogram(JNIEnv* env,
64 jstring j_histogram_name,
65 jint j_histogram_key) {
66 // These values are based on the hard-coded constants in the
67 // UMA_HISTOGRAM_COUNTS macro from base/metrics/histogram_macros.h.
68 const int histogram_min = 1;
69 const int histogram_max = 1000000;
70 const int histogram_num_buckets = 50;
72 DCHECK(j_histogram_name);
73 DCHECK(j_histogram_key);
74 HistogramBase* histogram = FindLocked(j_histogram_key);
75 if (histogram) {
76 DCHECK(histogram->HasConstructionArguments(histogram_min, histogram_max,
77 histogram_num_buckets));
78 return histogram;
81 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
82 histogram = Histogram::FactoryGet(histogram_name, histogram_min,
83 histogram_max, histogram_num_buckets,
84 HistogramBase::kUmaTargetedHistogramFlag);
85 return InsertLocked(j_histogram_key, histogram);
88 HistogramBase* CustomTimesHistogram(JNIEnv* env,
89 jstring j_histogram_name,
90 jint j_histogram_key,
91 jlong j_min,
92 jlong j_max,
93 jint j_bucket_count) {
94 DCHECK(j_histogram_name);
95 DCHECK(j_histogram_key);
96 HistogramBase* histogram = FindLocked(j_histogram_key);
97 int64 min = static_cast<int64>(j_min);
98 int64 max = static_cast<int64>(j_max);
99 int bucket_count = static_cast<int>(j_bucket_count);
100 if (histogram) {
101 DCHECK(histogram->HasConstructionArguments(min, max, bucket_count));
102 return histogram;
105 std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
106 // This intentionally uses FactoryGet and not FactoryTimeGet. FactoryTimeGet
107 // is just a convenience for constructing the underlying Histogram with
108 // TimeDelta arguments.
109 histogram = Histogram::FactoryGet(histogram_name, min, max, bucket_count,
110 HistogramBase::kUmaTargetedHistogramFlag);
111 return InsertLocked(j_histogram_key, histogram);
114 private:
115 HistogramBase* FindLocked(jint j_histogram_key) {
116 base::AutoLock locked(lock_);
117 auto histogram_it = histograms_.find(j_histogram_key);
118 return histogram_it != histograms_.end() ? histogram_it->second : nullptr;
121 HistogramBase* InsertLocked(jint j_histogram_key, HistogramBase* histogram) {
122 base::AutoLock locked(lock_);
123 histograms_.insert(std::make_pair(j_histogram_key, histogram));
124 return histogram;
127 base::Lock lock_;
128 std::map<jint, HistogramBase*> histograms_;
130 DISALLOW_COPY_AND_ASSIGN(HistogramCache);
133 base::LazyInstance<HistogramCache>::Leaky g_histograms;
135 } // namespace
137 void RecordBooleanHistogram(JNIEnv* env,
138 jclass clazz,
139 jstring j_histogram_name,
140 jint j_histogram_key,
141 jboolean j_sample) {
142 bool sample = static_cast<bool>(j_sample);
143 g_histograms.Get()
144 .BooleanHistogram(env, j_histogram_name, j_histogram_key)
145 ->AddBoolean(sample);
148 void RecordEnumeratedHistogram(JNIEnv* env,
149 jclass clazz,
150 jstring j_histogram_name,
151 jint j_histogram_key,
152 jint j_sample,
153 jint j_boundary) {
154 int sample = static_cast<int>(j_sample);
156 g_histograms.Get()
157 .EnumeratedHistogram(env, j_histogram_name, j_histogram_key, j_boundary)
158 ->Add(sample);
161 void RecordCountHistogram(JNIEnv* env,
162 jclass clazz,
163 jstring j_histogram_name,
164 jint j_histogram_key,
165 jint j_sample) {
166 int sample = static_cast<int>(j_sample);
168 g_histograms.Get()
169 .CountHistogram(env, j_histogram_name, j_histogram_key)
170 ->Add(sample);
173 void RecordCustomTimesHistogramMilliseconds(JNIEnv* env,
174 jclass clazz,
175 jstring j_histogram_name,
176 jint j_histogram_key,
177 jlong j_duration,
178 jlong j_min,
179 jlong j_max,
180 jint j_num_buckets) {
181 g_histograms.Get()
182 .CustomTimesHistogram(env, j_histogram_name, j_histogram_key, j_min,
183 j_max, j_num_buckets)
184 ->AddTime(TimeDelta::FromMilliseconds(static_cast<int64>(j_duration)));
187 void Initialize(JNIEnv* env, jclass) {
188 StatisticsRecorder::Initialize();
191 // This backs a Java test util for testing histograms -
192 // MetricsUtils.HistogramDelta. It should live in a test-specific file, but we
193 // currently can't have test-specific native code packaged in test-specific Java
194 // targets - see http://crbug.com/415945.
195 jint GetHistogramValueCountForTesting(JNIEnv* env,
196 jclass clazz,
197 jstring histogram_name,
198 jint sample) {
199 HistogramBase* histogram = StatisticsRecorder::FindHistogram(
200 android::ConvertJavaStringToUTF8(env, histogram_name));
201 if (histogram == nullptr) {
202 // No samples have been recorded for this histogram (yet?).
203 return 0;
206 scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
207 return samples->GetCount(static_cast<int>(sample));
210 bool RegisterRecordHistogram(JNIEnv* env) {
211 return RegisterNativesImpl(env);
214 } // namespace android
215 } // namespace base