| Index: chrome/browser/metrics/desktop_engagement_service.cc
|
| diff --git a/chrome/browser/metrics/desktop_engagement_service.cc b/chrome/browser/metrics/desktop_engagement_service.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6e1f23717aa62c9a5971d1cda49a538cafb09dbb
|
| --- /dev/null
|
| +++ b/chrome/browser/metrics/desktop_engagement_service.cc
|
| @@ -0,0 +1,121 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/metrics/desktop_engagement_service.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/metrics/histogram_macros.h"
|
| +#include "chrome/browser/metrics/chrome_visibility_observer.h"
|
| +
|
| +
|
| +namespace {
|
| +
|
| +DesktopEngagementService* g_instance = nullptr;
|
| +
|
| +const int kActivityIntervalMinutes = 1;
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +void DesktopEngagementService::Initialize() {
|
| + g_instance = new DesktopEngagementService;
|
| + metrics::ChromeVisibilityObserver::Initialize();
|
| +}
|
| +
|
| +// static
|
| +DesktopEngagementService* DesktopEngagementService::Get() {
|
| + DCHECK(g_instance);
|
| + return g_instance;
|
| +}
|
| +
|
| +void DesktopEngagementService::StartTimer(base::TimeDelta duration) {
|
| + timer_.Start(FROM_HERE, duration,
|
| + base::Bind(&DesktopEngagementService::OnTimerFired,
|
| + weak_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void DesktopEngagementService::OnVisibilityChanged(bool visible) {
|
| + is_visible_ = visible;
|
| + if (is_visible_) {
|
| + OnUserEvent();
|
| + } else if (in_session_) {
|
| + DLOG(ERROR) << "Ending session due to visibility change";
|
| + EndSession();
|
| + }
|
| +}
|
| +
|
| +void DesktopEngagementService::OnUserEvent() {
|
| + if (!is_visible_)
|
| + return;
|
| +
|
| + last_user_event_ = base::TimeTicks::Now();
|
| + // This may start session.
|
| + if (!in_session_) {
|
| + DLOG(ERROR) << "Starting session due to user event";
|
| + StartSession();
|
| + }
|
| +}
|
| +
|
| +void DesktopEngagementService::OnAudioStart() {
|
| + // This may start session.
|
| + is_audio_playing_ = true;
|
| + if (!in_session_) {
|
| + DLOG(ERROR) << "Starting session due to audio start";
|
| + StartSession();
|
| + }
|
| +}
|
| +
|
| +void DesktopEngagementService::OnAudioEnd() {
|
| + is_audio_playing_ = false;
|
| +
|
| + // If the timer is not running, this means that no user events happened in the
|
| + // last 5 minutes so the session can be terminated.
|
| + if (!timer_.IsRunning()) {
|
| + DLOG(ERROR) << "Ending session due to audio ending";
|
| + EndSession();
|
| + }
|
| +}
|
| +
|
| +DesktopEngagementService::DesktopEngagementService()
|
| + : session_start_(base::TimeTicks::Now()), last_user_event_(session_start_),
|
| + weak_factory_(this) {
|
| + StartSession();
|
| + // TODO: Add user events observers here, or add a static Get() method to
|
| + // DesktopEngagementService.
|
| +}
|
| +
|
| +DesktopEngagementService::~DesktopEngagementService() {
|
| +}
|
| +
|
| +void DesktopEngagementService::OnTimerFired() {
|
| + base::TimeDelta remaining = base::TimeTicks::Now() - last_user_event_;
|
| + if (remaining < base::TimeDelta::FromMinutes(kActivityIntervalMinutes)) {
|
| + StartTimer(remaining);
|
| + return;
|
| + }
|
| +
|
| + // No user events happened in the last 5 min. Terminate the session now.
|
| + if (!is_audio_playing_) {
|
| + DLOG(ERROR) << "Ending session after delay";
|
| + EndSession();
|
| + }
|
| +}
|
| +
|
| +void DesktopEngagementService::StartSession() {
|
| + in_session_ = true;
|
| + session_start_ = base::TimeTicks::Now();
|
| + StartTimer(base::TimeDelta::FromMinutes(kActivityIntervalMinutes));
|
| +}
|
| +
|
| +void DesktopEngagementService::EndSession() {
|
| + in_session_ = false;
|
| + base::TimeDelta delta = base::TimeTicks::Now() - session_start_;
|
| +
|
| + constexpr unsigned kNumTimeSlices = 60 / 5 * 24;
|
| + DLOG(ERROR) << "Logging session length of " << delta.InSeconds()
|
| + << " seconds.";
|
| + UMA_HISTOGRAM_CUSTOM_TIMES("Session.TotalDuration", delta,
|
| + base::TimeDelta::FromMilliseconds(1),
|
| + base::TimeDelta::FromHours(24), kNumTimeSlices);
|
| +}
|
|
|