This source file includes following definitions.
- LogMetricsInitSequence
- waiting_for_init_task_complete_
- Start
- Stop
- InitTaskComplete
- UploadFinished
- UploadCancelled
- SetUploadIntervalForTesting
- TriggerUpload
- ScheduleNextUpload
- BackOffUploadInterval
#include "chrome/browser/metrics/metrics_reporting_scheduler.h"
#include "base/compiler_specific.h"
#include "chrome/browser/metrics/metrics_service.h"
using base::TimeDelta;
namespace {
#if defined(OS_ANDROID) || defined(OS_IOS)
const int kInitialUploadIntervalSeconds = 15;
#else
const int kInitialUploadIntervalSeconds = 60;
#endif
#if defined(OS_ANDROID) || defined(OS_IOS)
const int kUnsentLogsIntervalSeconds = 3;
#else
const int kUnsentLogsIntervalSeconds = 15;
#endif
#if defined(OS_ANDROID) || defined(OS_IOS)
const int kStandardUploadIntervalSeconds = 5 * 60;
#else
const int kStandardUploadIntervalSeconds = 30 * 60;
#endif
const double kBackoffMultiplier = 1.1;
const int kMaxBackoffMultiplier = 10;
enum InitSequence {
TIMER_FIRED_FIRST,
INIT_TASK_COMPLETED_FIRST,
INIT_SEQUENCE_ENUM_SIZE,
};
void LogMetricsInitSequence(InitSequence sequence) {
UMA_HISTOGRAM_ENUMERATION("UMA.InitSequence", sequence,
INIT_SEQUENCE_ENUM_SIZE);
}
}
MetricsReportingScheduler::MetricsReportingScheduler(
const base::Closure& upload_callback)
: upload_callback_(upload_callback),
upload_interval_(TimeDelta::FromSeconds(kInitialUploadIntervalSeconds)),
running_(false),
callback_pending_(false),
init_task_complete_(false),
waiting_for_init_task_complete_(false) {
}
MetricsReportingScheduler::~MetricsReportingScheduler() {}
void MetricsReportingScheduler::Start() {
running_ = true;
ScheduleNextUpload();
}
void MetricsReportingScheduler::Stop() {
running_ = false;
if (upload_timer_.IsRunning())
upload_timer_.Stop();
}
void MetricsReportingScheduler::InitTaskComplete() {
DCHECK(!init_task_complete_);
init_task_complete_ = true;
if (waiting_for_init_task_complete_) {
waiting_for_init_task_complete_ = false;
TriggerUpload();
} else {
LogMetricsInitSequence(INIT_TASK_COMPLETED_FIRST);
}
}
void MetricsReportingScheduler::UploadFinished(bool server_is_healthy,
bool more_logs_remaining) {
DCHECK(callback_pending_);
callback_pending_ = false;
if (!server_is_healthy) {
BackOffUploadInterval();
} else if (more_logs_remaining) {
upload_interval_ = TimeDelta::FromSeconds(kUnsentLogsIntervalSeconds);
} else {
upload_interval_ = TimeDelta::FromSeconds(kStandardUploadIntervalSeconds);
}
if (running_)
ScheduleNextUpload();
}
void MetricsReportingScheduler::UploadCancelled() {
DCHECK(callback_pending_);
callback_pending_ = false;
if (running_)
ScheduleNextUpload();
}
void MetricsReportingScheduler::SetUploadIntervalForTesting(
base::TimeDelta interval) {
upload_interval_ = interval;
}
void MetricsReportingScheduler::TriggerUpload() {
if (!init_task_complete_) {
LogMetricsInitSequence(TIMER_FIRED_FIRST);
waiting_for_init_task_complete_ = true;
return;
}
callback_pending_ = true;
upload_callback_.Run();
}
void MetricsReportingScheduler::ScheduleNextUpload() {
DCHECK(running_);
if (upload_timer_.IsRunning() || callback_pending_)
return;
upload_timer_.Start(FROM_HERE, upload_interval_, this,
&MetricsReportingScheduler::TriggerUpload);
}
void MetricsReportingScheduler::BackOffUploadInterval() {
DCHECK_GT(kBackoffMultiplier, 1.0);
upload_interval_ = TimeDelta::FromMicroseconds(
static_cast<int64>(kBackoffMultiplier *
upload_interval_.InMicroseconds()));
TimeDelta max_interval = kMaxBackoffMultiplier *
TimeDelta::FromSeconds(kStandardUploadIntervalSeconds);
if (upload_interval_ > max_interval || upload_interval_.InSeconds() < 0) {
upload_interval_ = max_interval;
}
}