1// Copyright (c) 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 "base/test/simple_test_tick_clock.h"
6#include "content/common/view_messages.h"
7#include "content/public/test/mock_render_thread.h"
8#include "content/renderer/media/render_media_log.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11namespace content {
12
13class RenderMediaLogTest : public testing::Test {
14 public:
15  RenderMediaLogTest()
16      : log_(new RenderMediaLog()),
17        tick_clock_(new base::SimpleTestTickClock()) {
18    log_->SetTickClockForTesting(scoped_ptr<base::TickClock>(tick_clock_));
19  }
20
21  virtual ~RenderMediaLogTest() {}
22
23  void AddEvent(media::MediaLogEvent::Type type) {
24    log_->AddEvent(log_->CreateEvent(type));
25  }
26
27  void Advance(base::TimeDelta delta) { tick_clock_->Advance(delta); }
28
29  int message_count() { return render_thread_.sink().message_count(); }
30
31  std::vector<media::MediaLogEvent> GetMediaLogEvents() {
32    const IPC::Message* msg = render_thread_.sink().GetFirstMessageMatching(
33        ViewHostMsg_MediaLogEvents::ID);
34    if (!msg) {
35      ADD_FAILURE() << "Did not find ViewHostMsg_MediaLogEvents IPC message";
36      return std::vector<media::MediaLogEvent>();
37    }
38
39    Tuple1<std::vector<media::MediaLogEvent> > events;
40    ViewHostMsg_MediaLogEvents::Read(msg, &events);
41    return events.a;
42  }
43
44 private:
45  MockRenderThread render_thread_;
46  scoped_refptr<RenderMediaLog> log_;
47  base::SimpleTestTickClock* tick_clock_;  // Owned by |log_|.
48
49  DISALLOW_COPY_AND_ASSIGN(RenderMediaLogTest);
50};
51
52TEST_F(RenderMediaLogTest, ThrottleSendingEvents) {
53  AddEvent(media::MediaLogEvent::LOAD);
54  EXPECT_EQ(0, message_count());
55
56  // Still shouldn't send anything.
57  Advance(base::TimeDelta::FromMilliseconds(500));
58  AddEvent(media::MediaLogEvent::SEEK);
59  EXPECT_EQ(0, message_count());
60
61  // Now we should expect an IPC.
62  Advance(base::TimeDelta::FromMilliseconds(500));
63  AddEvent(media::MediaLogEvent::PLAY);
64  EXPECT_EQ(1, message_count());
65
66  // Verify contents.
67  std::vector<media::MediaLogEvent> events = GetMediaLogEvents();
68  ASSERT_EQ(3u, events.size());
69  EXPECT_EQ(media::MediaLogEvent::LOAD, events[0].type);
70  EXPECT_EQ(media::MediaLogEvent::SEEK, events[1].type);
71  EXPECT_EQ(media::MediaLogEvent::PLAY, events[2].type);
72
73  // Adding another event shouldn't send anything.
74  AddEvent(media::MediaLogEvent::PIPELINE_ERROR);
75  EXPECT_EQ(1, message_count());
76}
77
78TEST_F(RenderMediaLogTest, BufferedExtents) {
79  AddEvent(media::MediaLogEvent::LOAD);
80  AddEvent(media::MediaLogEvent::SEEK);
81
82  // This event is handled separately and should always appear last regardless
83  // of how many times we see it.
84  AddEvent(media::MediaLogEvent::BUFFERED_EXTENTS_CHANGED);
85  AddEvent(media::MediaLogEvent::BUFFERED_EXTENTS_CHANGED);
86  AddEvent(media::MediaLogEvent::BUFFERED_EXTENTS_CHANGED);
87
88  // Trigger IPC message.
89  EXPECT_EQ(0, message_count());
90  Advance(base::TimeDelta::FromMilliseconds(1000));
91  AddEvent(media::MediaLogEvent::PLAY);
92  EXPECT_EQ(1, message_count());
93
94  // Verify contents. There should only be a single buffered extents changed
95  // event.
96  std::vector<media::MediaLogEvent> events = GetMediaLogEvents();
97  ASSERT_EQ(4u, events.size());
98  EXPECT_EQ(media::MediaLogEvent::LOAD, events[0].type);
99  EXPECT_EQ(media::MediaLogEvent::SEEK, events[1].type);
100  EXPECT_EQ(media::MediaLogEvent::PLAY, events[2].type);
101  EXPECT_EQ(media::MediaLogEvent::BUFFERED_EXTENTS_CHANGED, events[3].type);
102}
103
104}  // namespace content
105