| Index: base/android/record_histogram.cc
|
| diff --git a/base/android/record_histogram.cc b/base/android/record_histogram.cc
|
| index 9a72460fe550b42a584c95d2b30bcda133a71e4b..9549adc274a4fd53e519f1c4c8c1bfa4a09408eb 100644
|
| --- a/base/android/record_histogram.cc
|
| +++ b/base/android/record_histogram.cc
|
| @@ -2,39 +2,108 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include "base/android/record_histogram.h"
|
| +
|
| +#include <map>
|
| +
|
| #include "base/android/jni_android.h"
|
| #include "base/android/jni_string.h"
|
| -#include "base/android/record_histogram.h"
|
| +#include "base/lazy_instance.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/metrics/statistics_recorder.h"
|
| +#include "base/synchronization/lock.h"
|
| #include "jni/RecordHistogram_jni.h"
|
|
|
| namespace base {
|
| namespace android {
|
| +namespace {
|
| +
|
| +// Simple thread-safe wrapper for caching histograms. This avoids
|
| +// relatively expensive JNI string translation for each recording.
|
| +class HistogramCache {
|
| + public:
|
| + HistogramCache() {}
|
| +
|
| + HistogramBase* BooleanHistogram(JNIEnv* env,
|
| + jstring j_histogram_name,
|
| + jint j_histogram_key) {
|
| + DCHECK(j_histogram_name);
|
| + DCHECK(j_histogram_key);
|
| + HistogramBase* histogram = FindLocked(j_histogram_key);
|
| + if (histogram)
|
| + return histogram;
|
| +
|
| + std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
|
| + histogram = BooleanHistogram::FactoryGet(
|
| + histogram_name, HistogramBase::kUmaTargetedHistogramFlag);
|
| + return InsertLocked(j_histogram_key, histogram);
|
| + }
|
| +
|
| + HistogramBase* EnumeratedHistogram(JNIEnv* env,
|
| + jstring j_histogram_name,
|
| + jint j_histogram_key,
|
| + jint j_boundary) {
|
| + DCHECK(j_histogram_name);
|
| + DCHECK(j_histogram_key);
|
| + HistogramBase* histogram = FindLocked(j_histogram_key);
|
| + if (histogram)
|
| + return histogram;
|
| +
|
| + std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
|
| + // Note: This caching bypasses the boundary validation that occurs between
|
| + // repeated lookups by the same name. It is up to the caller to ensure that
|
| + // the provided boundary remains consistent.
|
| + int boundary = static_cast<int>(j_boundary);
|
| + histogram =
|
| + LinearHistogram::FactoryGet(histogram_name, 1, boundary, boundary + 1,
|
| + HistogramBase::kUmaTargetedHistogramFlag);
|
| + return InsertLocked(j_histogram_key, histogram);
|
| + }
|
| +
|
| + private:
|
| + HistogramBase* FindLocked(jint j_histogram_key) {
|
| + base::AutoLock locked(lock_);
|
| + auto histogram_it = histograms_.find(j_histogram_key);
|
| + return histogram_it != histograms_.end() ? histogram_it->second : nullptr;
|
| + }
|
| +
|
| + HistogramBase* InsertLocked(jint j_histogram_key, HistogramBase* histogram) {
|
| + base::AutoLock locked(lock_);
|
| + histograms_.insert(std::make_pair(j_histogram_key, histogram));
|
| + return histogram;
|
| + }
|
| +
|
| + base::Lock lock_;
|
| + std::map<jint, HistogramBase*> histograms_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(HistogramCache);
|
| +};
|
| +
|
| +base::LazyInstance<HistogramCache>::Leaky g_histograms;
|
| +
|
| +} // namespace
|
|
|
| void RecordBooleanHistogram(JNIEnv* env,
|
| jclass clazz,
|
| jstring j_histogram_name,
|
| + jint j_histogram_key,
|
| jboolean j_sample) {
|
| - std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
|
| bool sample = static_cast<bool>(j_sample);
|
| -
|
| - BooleanHistogram::FactoryGet(histogram_name,
|
| - HistogramBase::kUmaTargetedHistogramFlag)
|
| + g_histograms.Get()
|
| + .BooleanHistogram(env, j_histogram_name, j_histogram_key)
|
| ->AddBoolean(sample);
|
| }
|
|
|
| void RecordEnumeratedHistogram(JNIEnv* env,
|
| jclass clazz,
|
| jstring j_histogram_name,
|
| + jint j_histogram_key,
|
| jint j_sample,
|
| jint j_boundary) {
|
| - std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
|
| int sample = static_cast<int>(j_sample);
|
| - int boundary = static_cast<int>(j_boundary);
|
|
|
| - LinearHistogram::FactoryGet(histogram_name, 1, boundary, boundary + 1,
|
| - HistogramBase::kUmaTargetedHistogramFlag)
|
| + g_histograms.Get()
|
| + .EnumeratedHistogram(env, j_histogram_name, j_histogram_key, j_boundary)
|
| ->Add(sample);
|
| }
|
|
|
|
|