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.
4
5#include "content/browser/renderer_host/media/media_stream_track_metrics_host.h"
6
7#include "base/metrics/histogram.h"
8#include "content/common/media/media_stream_track_metrics_host_messages.h"
9
10// We use a histogram with a maximum bucket of 16 hours to infinity
11// for track durations.
12#define UMA_HISTOGRAM_TIMES_16H(name, sample)                        \
13  UMA_HISTOGRAM_CUSTOM_TIMES(name, sample,                           \
14                             base::TimeDelta::FromMilliseconds(100), \
15                             base::TimeDelta::FromHours(16),         \
16                             50);
17
18namespace content {
19
20MediaStreamTrackMetricsHost::MediaStreamTrackMetricsHost()
21    : BrowserMessageFilter(MediaStreamTrackMetricsHostMsgStart) {
22}
23
24MediaStreamTrackMetricsHost::~MediaStreamTrackMetricsHost() {
25  // Our render process has exited. We won't receive any more IPC
26  // messages from it. Assume all tracks ended now.
27  for (TrackMap::iterator it = tracks_.begin();
28       it != tracks_.end();
29       ++it) {
30    TrackInfo& info = it->second;
31    ReportDuration(info);
32  }
33  tracks_.clear();
34}
35
36bool MediaStreamTrackMetricsHost::OnMessageReceived(
37    const IPC::Message& message) {
38  bool handled = true;
39
40  IPC_BEGIN_MESSAGE_MAP(MediaStreamTrackMetricsHost, message)
41    IPC_MESSAGE_HANDLER(MediaStreamTrackMetricsHost_AddTrack, OnAddTrack)
42    IPC_MESSAGE_HANDLER(MediaStreamTrackMetricsHost_RemoveTrack, OnRemoveTrack)
43    IPC_MESSAGE_UNHANDLED(handled = false)
44  IPC_END_MESSAGE_MAP()
45
46  return handled;
47}
48
49void MediaStreamTrackMetricsHost::OnAddTrack(uint64 id,
50                                             bool is_audio,
51                                             bool is_remote) {
52  if (tracks_.find(id) != tracks_.end())
53    return;
54
55  TrackInfo info = {is_audio, is_remote, base::TimeTicks::Now()};
56  tracks_[id] = info;
57}
58
59void MediaStreamTrackMetricsHost::OnRemoveTrack(uint64 id) {
60  if (tracks_.find(id) == tracks_.end())
61    return;
62
63  TrackInfo& info = tracks_[id];
64  ReportDuration(info);
65  tracks_.erase(id);
66}
67
68void MediaStreamTrackMetricsHost::ReportDuration(const TrackInfo& info) {
69  base::TimeDelta duration = base::TimeTicks::Now() - info.timestamp;
70  if (info.is_remote) {
71    if (info.is_audio) {
72      DVLOG(3) << "WebRTC.ReceivedAudioTrackDuration: " << duration.InSeconds();
73      UMA_HISTOGRAM_TIMES_16H("WebRTC.ReceivedAudioTrackDuration", duration);
74    } else {
75      DVLOG(3) << "WebRTC.ReceivedVideoTrackDuration: " << duration.InSeconds();
76      UMA_HISTOGRAM_TIMES_16H("WebRTC.ReceivedVideoTrackDuration", duration);
77    }
78  } else {
79    if (info.is_audio) {
80      DVLOG(3) << "WebRTC.SentAudioTrackDuration: " << duration.InSeconds();
81      UMA_HISTOGRAM_TIMES_16H("WebRTC.SentAudioTrackDuration", duration);
82    } else {
83      DVLOG(3) << "WebRTC.SentVideoTrackDuration: " << duration.InSeconds();
84      UMA_HISTOGRAM_TIMES_16H("WebRTC.SentVideoTrackDuration", duration);
85    }
86  }
87}
88
89}  // namespace content
90