16b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET/*
26b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET * Copyright (C) 2015 The Android Open Source Project
36b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET *
46b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET * Licensed under the Apache License, Version 2.0 (the "License");
56b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET * you may not use this file except in compliance with the License.
66b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET * You may obtain a copy of the License at
76b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET *
86b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET *      http://www.apache.org/licenses/LICENSE-2.0
96b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET *
106b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET * Unless required by applicable law or agreed to in writing, software
116b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET * distributed under the License is distributed on an "AS IS" BASIS,
126b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET * See the License for the specific language governing permissions and
146b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET * limitations under the License.
156b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET */
166b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET
176b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET#include "uploader/bn_metricsd_impl.h"
186b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET
196b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET#include <base/metrics/histogram.h>
206b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET#include <base/metrics/sparse_histogram.h>
21b13527d14eacf6fbed4e5f7be8245755279c203eBertrand SIMONNET#include <base/metrics/statistics_recorder.h>
222862a7843dbec433c78febaed5c4c6c64500078bTodd Poynor#include <utils/Errors.h>
236b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET#include <utils/String16.h>
246b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET#include <utils/String8.h>
256b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET
266b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETusing android::binder::Status;
276b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETusing android::String16;
286b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET
296b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETstatic const char16_t kCrashTypeKernel[] = u"kernel";
306b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETstatic const char16_t kCrashTypeUncleanShutdown[] = u"uncleanshutdown";
316b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETstatic const char16_t kCrashTypeUser[] = u"user";
326b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET
336b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETBnMetricsdImpl::BnMetricsdImpl(const std::shared_ptr<CrashCounters>& counters)
346b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET    : counters_(counters) {
352862a7843dbec433c78febaed5c4c6c64500078bTodd Poynor  CHECK(counters_) << "Invalid counters argument to constructor";
366b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET}
376b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET
386b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETStatus BnMetricsdImpl::recordHistogram(
396b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET    const String16& name, int sample, int min, int max, int nbuckets) {
406b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  base::HistogramBase* histogram = base::Histogram::FactoryGet(
416b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET      android::String8(name).string(), min, max, nbuckets,
426b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET      base::Histogram::kUmaTargetedHistogramFlag);
436b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  // |histogram| may be null if a client reports two contradicting histograms
446b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  // with the same name but different limits.
456b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  // FactoryGet will print a useful message if that is the case.
466b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  if (histogram) {
476b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET    histogram->Add(sample);
486b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  }
496b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  return Status::ok();
506b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET}
516b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET
526b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETStatus BnMetricsdImpl::recordLinearHistogram(const String16& name,
536b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET                                             int sample,
546b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET                                             int max) {
556b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  base::HistogramBase* histogram = base::LinearHistogram::FactoryGet(
566b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET      android::String8(name).string(), 1, max, max + 1,
576b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET      base::Histogram::kUmaTargetedHistogramFlag);
586b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  // |histogram| may be null if a client reports two contradicting histograms
596b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  // with the same name but different limits.
606b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  // FactoryGet will print a useful message if that is the case.
616b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  if (histogram) {
626b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET    histogram->Add(sample);
636b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  }
646b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  return Status::ok();
656b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET}
666b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET
676b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETStatus BnMetricsdImpl::recordSparseHistogram(const String16& name, int sample) {
686b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  base::HistogramBase* histogram = base::SparseHistogram::FactoryGet(
696b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET      android::String8(name).string(),
706b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET      base::Histogram::kUmaTargetedHistogramFlag);
716b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  // |histogram| may be null if a client reports two contradicting histograms
726b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  // with the same name but different limits.
736b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  // FactoryGet will print a useful message if that is the case.
746b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  if (histogram) {
756b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET    histogram->Add(sample);
766b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  }
776b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  return Status::ok();
786b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET}
796b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET
806b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNETStatus BnMetricsdImpl::recordCrash(const String16& type) {
816b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  if (type == kCrashTypeUser) {
826b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET    counters_->IncrementUserCrashCount();
836b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  } else if (type == kCrashTypeKernel) {
846b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET    counters_->IncrementKernelCrashCount();
856b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  } else if (type == kCrashTypeUncleanShutdown) {
866b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET    counters_->IncrementUncleanShutdownCount();
876b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  } else {
886b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET    LOG(ERROR) << "Unknown crash type received: " << type;
896b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  }
906b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET  return Status::ok();
916b8629a6490d01196368ae1ed5bc6967c6f127ebBertrand SIMONNET}
92b13527d14eacf6fbed4e5f7be8245755279c203eBertrand SIMONNET
93b13527d14eacf6fbed4e5f7be8245755279c203eBertrand SIMONNETStatus BnMetricsdImpl::getHistogramsDump(String16* dump) {
94b13527d14eacf6fbed4e5f7be8245755279c203eBertrand SIMONNET  std::string str_dump;
95b13527d14eacf6fbed4e5f7be8245755279c203eBertrand SIMONNET  base::StatisticsRecorder::WriteGraph(std::string(), &str_dump);
96b13527d14eacf6fbed4e5f7be8245755279c203eBertrand SIMONNET  *dump = String16(str_dump.c_str());
97b13527d14eacf6fbed4e5f7be8245755279c203eBertrand SIMONNET  return Status::ok();
98b13527d14eacf6fbed4e5f7be8245755279c203eBertrand SIMONNET}
99