Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Unified Diff: media/base/text_renderer_unittest.cc

Issue 23702007: Render inband text tracks in the media pipeline (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: incorporate aaron's comments (11/04) Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/base/text_renderer_unittest.cc
diff --git a/media/base/text_renderer_unittest.cc b/media/base/text_renderer_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5c30abdeec8dfb5773f449278f162d67f9834e13
--- /dev/null
+++ b/media/base/text_renderer_unittest.cc
@@ -0,0 +1,3284 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 nit: s/ (c)// New files are supposed to use a head
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/memory/scoped_vector.h"
+#include "base/message_loop/message_loop.h"
+#include "media/base/audio_decoder_config.h"
+#include "media/base/decoder_buffer.h"
+#include "media/base/demuxer_stream.h"
+#include "media/base/text_renderer.h"
+#include "media/base/text_track_config.h"
+#include "media/base/video_decoder_config.h"
+#include "media/filters/webvtt_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::Invoke;
+using ::testing::_;
+
+namespace media {
+
+class TextRendererTest;
+class TextTrackTest;
+
+// To store the cue delivered by the text renderer, when it receives
+// a decoder buffer.
+struct TextCueTest {
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 This looks almost identical to the TextCue object.
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+ base::TimeDelta start_;
+ base::TimeDelta end_;
+ std::string id_;
+ std::string content_;
+ std::string settings_;
+
+ TextCueTest(const base::TimeDelta& start,
+ const base::TimeDelta& end,
+ const std::string& id,
+ const std::string& content,
+ const std::string& settings)
+ : start_(start),
+ end_(end),
+ id_(id),
+ content_(content),
+ settings_(settings) {
+ }
+};
+
+// Grant last wishes to the TextTrackTest object.
+void RemoveTextTrackTest(TextRendererTest* text_renderer_test,
+ TextTrackTest* text_track);
+
+// A local implementation of the TextTrack interface. It simply
+// stores the cue(s) delivered by the text renderer, allowing the
+// this test framework to compare the cue received to the cue
+// pushed downstream.
+class TextTrackTest : public TextTrack {
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 nit:s/TextTrackTest/FakeTextTrack/ since this is a
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+ public:
+ TextTrackTest(TextRendererTest* text_renderer_test,
+ unsigned idx,
+ const TextTrackConfig& config)
+ : text_renderer_test_(text_renderer_test),
+ index_(idx),
+ config_(config) {
+ }
+ virtual ~TextTrackTest() {
+ RemoveTextTrackTest(text_renderer_test_, this);
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 Pass a Closure into the constructor instead so thi
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+ }
+ virtual void addWebVTTCue(const base::TimeDelta& start,
+ const base::TimeDelta& end,
+ const std::string& id,
+ const std::string& content,
+ const std::string& settings) OVERRIDE {
+ cues_.push_back(TextCueTest(start, end, id, content, settings));
+ }
+
+ TextRendererTest* const text_renderer_test_;
+
+ // Index of this TextTrack object in the vector of such objects
+ // maintained by the TextRendererTest object.
+ const unsigned index_;
+
+ const TextTrackConfig config_;
+
+ typedef std::vector<TextCueTest> Cues;
+ Cues cues_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextTrackTest);
+};
+
+// Local implementation of the DemuxerStream. These are the stream objects
+// we pass to the text renderer object when streams are added and removed.
+class TextTrackStream : public DemuxerStream {
+ public:
+ TextTrackStream()
+ : message_loop_(base::MessageLoopProxy::current()) {
+ }
+ virtual ~TextTrackStream() {
+ DCHECK(read_cb_.is_null());
+ }
+
+ // DemuxerStream implementation.
+ MOCK_METHOD1(Read, void(const ReadCB&));
+ MOCK_METHOD0(audio_decoder_config, AudioDecoderConfig());
+ MOCK_METHOD0(video_decoder_config, VideoDecoderConfig());
+ virtual Type type() OVERRIDE { return DemuxerStream::TEXT; }
+ MOCK_METHOD0(EnableBitstreamConverter, void());
+
+ // Local methods
+
+ void DoRead(const ReadCB& read_cb) {
+ EXPECT_FALSE(read_cb.is_null());
+ EXPECT_TRUE(read_cb_.is_null());
+ read_cb_ = read_cb;
+ }
+
+ void SatisfyPendingRead(const base::TimeDelta& start,
+ const base::TimeDelta& duration,
+ const std::string& id,
+ const std::string& content,
+ const std::string& settings) {
+ EXPECT_FALSE(read_cb_.is_null());
+
+ const uint8* const data = reinterpret_cast<const uint8*>(content.data());
+
+ std::vector<uint8> side_data;
+ MakeSideData(id.begin(), id.end(),
+ settings.begin(), settings.end(),
+ &side_data);
+
+ scoped_refptr<DecoderBuffer> buffer;
+
+ buffer = DecoderBuffer::CopyFrom(data,
+ content.size(),
+ side_data.data(),
+ side_data.size());
+
+ buffer->set_timestamp(start);
+ buffer->set_duration(duration);
+
+ base::ResetAndReturn(&read_cb_).Run(kOk, buffer);
+ }
+
+ void AbortPendingRead() {
+ EXPECT_FALSE(read_cb_.is_null());
+ base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
+ }
+
+ void SendEosNotification() {
+ EXPECT_FALSE(read_cb_.is_null());
+ base::ResetAndReturn(&read_cb_).Run(kOk, DecoderBuffer::CreateEOSBuffer());
+ }
+
+ scoped_refptr<base::MessageLoopProxy> message_loop_;
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 Why do you need this? It doesn't look like you are
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+ ReadCB read_cb_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextTrackStream);
+};
+
+class TextRendererTest : public testing::Test {
+ public:
+ TextRendererTest() {}
+
+ void CreateTextRenderer() {
+ DCHECK(!text_renderer_);
+
+ text_renderer_.reset(
+ new TextRenderer(message_loop_.message_loop_proxy(),
+ base::Bind(&TextRendererTest::OnAddTextTrack,
+ base::Unretained(this))));
+ text_renderer_->Initialize(base::Bind(&TextRendererTest::OnEnd,
+ base::Unretained(this)));
+ }
+
+ void DestroyTextRenderer() {
+ EXPECT_CALL(*this, OnStop());
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+ }
+
+ TextTrackStream* CreateTextTrack() {
+ text_track_streams_.push_back(new TextTrackStream);
+ return text_track_streams_.back();
+ }
+
+ void AddTextTrack(TextKind kind,
+ const std::string& name,
+ const std::string& language) {
+ EXPECT_CALL(*this, OnAddTextTrack(_,_))
+ .WillOnce(Invoke(this, &TextRendererTest::DoAddTextTrack));
+
+ const TextTrackConfig config(kind, name, language);
+ text_renderer_->AddTextStream(text_track_streams_.back(), config);
+ message_loop_.RunUntilIdle();
+
+ EXPECT_FALSE(text_tracks_.empty());
+ TextTrackTest* const text_track = text_tracks_.back();
+ EXPECT_TRUE(text_track->config_.Matches(config));
+ }
+
+ MOCK_METHOD2(OnAddTextTrack, void(const TextTrackConfig&,
+ const AddTextTrackDoneCB&));
+
+ void DoAddTextTrack(const TextTrackConfig& config,
+ const AddTextTrackDoneCB& done_cb) {
+ const unsigned idx = text_tracks_.size();
+ scoped_ptr<TextTrackTest> text_track(new TextTrackTest(this,
+ idx,
+ config));
+ // text_track is owned by text renderer, but we cache it here so we
+ // can inspect it. It gets removed from the cache when the text renderer
+ // deallocates it.
+ text_tracks_.push_back(text_track.get());
+ done_cb.Run(text_track.Pass());
+ }
+
+ void SatisfyPendingReads(const base::TimeDelta& start,
+ const base::TimeDelta& duration,
+ const std::string& id,
+ const std::string& content,
+ const std::string& settings) {
+ for (TextTrackStreams::iterator itr = text_track_streams_.begin();
+ itr != text_track_streams_.end(); ++itr) {
+ (*itr)->SatisfyPendingRead(start, duration, id, content, settings);
+ }
+ }
+
+ void AbortPendingReads() {
+ for (TextTrackStreams::iterator itr = text_track_streams_.begin();
+ itr != text_track_streams_.end(); ++itr) {
+ (*itr)->AbortPendingRead();
+ }
+ }
+
+ void SendEosNotifications() {
+ for (TextTrackStreams::iterator itr = text_track_streams_.begin();
+ itr != text_track_streams_.end(); ++itr) {
+ (*itr)->SendEosNotification();
+ }
+ }
+
+ void SendCues(bool expect_cue) {
+ DCHECK(text_track_streams_.size() == text_tracks_.size());
+
+ const base::TimeDelta start;
+ const base::TimeDelta duration = base::TimeDelta::FromSeconds(42);
+ std::string id = "stratford-on-guy";
+ std::string content = "Yo Yo Buddy Yup Yup Word To Ya Muthuh";
+ std::string settings = "";
+ SatisfyPendingReads(start, duration, id, content, settings);
+
+ message_loop_.RunUntilIdle();
+
+ for (TextTracks::iterator itr = text_tracks_.begin();
+ itr != text_tracks_.end(); ++itr) {
+ TextTrackTest* const text_track = *itr;
+
+ TextTrackTest::Cues& cues = text_track->cues_;
+
+ if (cues.empty()) {
+ EXPECT_FALSE(expect_cue);
+ continue;
+ }
+
+ EXPECT_TRUE(expect_cue);
+ ASSERT_EQ(cues.size(), 1);
+
+ TextCueTest& cue = cues.back();
+ EXPECT_EQ(cue.start_, start);
+ EXPECT_EQ(cue.end_, start + duration);
+ EXPECT_EQ(cue.id_, id);
+ EXPECT_EQ(cue.content_, content);
+ EXPECT_EQ(cue.settings_, settings);
+ }
+ }
+
+ void SendCue(unsigned idx, bool expect_cue) {
+ TextTrackStream* const text_stream = text_track_streams_[idx];
+
+ const base::TimeDelta start;
+ const base::TimeDelta duration = base::TimeDelta::FromSeconds(42);
+ std::string id = "Dance Of The Seven Veils";
+ std::string content = "Girly Sound";
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 nit: I think we should have more neutral test text
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+ std::string settings = "";
+ text_stream->SatisfyPendingRead(start, duration, id, content, settings);
+
+ message_loop_.RunUntilIdle();
+
+ TextTrackTest* const text_track = text_tracks_[idx];
+
+ TextTrackTest::Cues& cues = text_track->cues_;
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 Do you really need to keep the cues around? It see
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+
+ if (cues.empty()) {
+ EXPECT_FALSE(expect_cue);
+ return;
+ }
+
+ EXPECT_TRUE(expect_cue);
+ ASSERT_EQ(cues.size(), 1);
+
+ TextCueTest& cue = cues.back();
+ EXPECT_EQ(cue.start_, start);
+ EXPECT_EQ(cue.end_, start + duration);
+ EXPECT_EQ(cue.id_, id);
+ EXPECT_EQ(cue.content_, content);
+ EXPECT_EQ(cue.settings_, settings);
+ }
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 To avoid duplicate code, it seems like SendCues()
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+
+ void RemoveTextTrackTest(TextTrackTest* text_track_test) {
+ const unsigned idx = text_track_test->index_;
+ DCHECK(text_tracks_[idx] == text_track_test);
+ text_tracks_[idx] = NULL;
+ }
+
+ MOCK_METHOD0(OnEnd, void());
+ MOCK_METHOD0(OnStop, void());
+ MOCK_METHOD0(OnPlay, void());
+ MOCK_METHOD0(OnPause, void());
+ MOCK_METHOD0(OnFlush, void());
+
+ scoped_ptr<TextRenderer> text_renderer_;
+ base::MessageLoop message_loop_;
+
+ typedef ScopedVector<TextTrackStream> TextTrackStreams;
+ TextTrackStreams text_track_streams_;
+
+ typedef std::vector<TextTrackTest*> TextTracks;
+ TextTracks text_tracks_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextRendererTest);
+};
+
+void RemoveTextTrackTest(TextRendererTest* text_renderer_test,
+ TextTrackTest* text_track) {
+ text_renderer_test->RemoveTextTrackTest(text_track);
+}
+
+TEST_F(TextRendererTest, CreateTextRendererNoInit) {
+ text_renderer_.reset(
+ new TextRenderer(message_loop_.message_loop_proxy(),
+ base::Bind(&TextRendererTest::OnAddTextTrack,
+ base::Unretained(this))));
+ text_renderer_.reset();
+}
+
+TEST_F(TextRendererTest, TestStop) {
+ CreateTextRenderer();
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTextTrackOnly) {
+ CreateTextRenderer();
+ CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTextTracks2Only) {
+ CreateTextRenderer();
+ CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "track 1", "");
+ CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "track 2", "");
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayOnly) {
+ CreateTextRenderer();
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackBeforePlay) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 I think it might be better if you change DoRead()
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 nit: In almost all cases where Play() is called it
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackBeforePlay2) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackAfterPlay) {
+ CreateTextRenderer();
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "", "");
+
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackAfterPlay2A) {
+ CreateTextRenderer();
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackAfterPlay2B) {
acolwell GONE FROM CHROMIUM 2013/11/10 19:48:08 nit: Typically when we have variants of the same t
Matthew Heaney (Chromium) 2013/11/13 05:44:49 Done.
+ CreateTextRenderer();
+
+ EXPECT_CALL(*this, OnPlay());
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayAddCue) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCues(true);
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayAddCue2) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCues(true);
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosOnly) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosOnly2) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCueEos) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCues(true);
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCueEos2) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream_2, &TextTrackStream::DoRead));
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCues(true);
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, TestStopPending) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+
+ EXPECT_CALL(*this, OnStop());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+}
+
+TEST_F(TextRendererTest, TestStopPending2) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+
+ EXPECT_CALL(*this, OnStop());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+}
+
+TEST_F(TextRendererTest, PlayPause) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayPause2) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPausePending) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPausePending2) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCuePausePending) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ SendCues(true);
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCuePausePending2) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ SendCues(true);
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2A) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2B) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosFlush) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnFlush());
+ text_renderer_->Flush(base::Bind(&TextRendererTest::OnFlush,
+ base::Unretained(this)));
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosFlush2) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnFlush());
+ text_renderer_->Flush(base::Bind(&TextRendererTest::OnFlush,
+ base::Unretained(this)));
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTextTrackOnlyRemove) {
+ CreateTextRenderer();
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTextTracks2OnlyRemove) {
+ CreateTextRenderer();
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "track 1", "");
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "track 2", "");
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackBeforePlayRemove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackBeforePlay2RemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackBeforePlay2RemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackBeforePlay2RemoveC) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackBeforePlay2RemoveD) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackAfterPlayRemove) {
+ CreateTextRenderer();
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "", "");
+
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackAfterPlay2ARemoveA) {
+ CreateTextRenderer();
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackAfterPlay2ARemoveB) {
+ CreateTextRenderer();
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddTrackAfterPlay2BRemove) {
+ CreateTextRenderer();
+
+ EXPECT_CALL(*this, OnPlay());
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayAddCueRemove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCues(true);
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayAddCue2Remove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCues(true);
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosOnlyRemove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosOnly2Remove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCueEosRemove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCues(true);
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCueEos2Remove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(text_stream_2, &TextTrackStream::DoRead));
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCues(true);
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, TestStopPendingRemove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+
+ EXPECT_CALL(*this, OnStop());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+}
+
+TEST_F(TextRendererTest, TestStopPending2RemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnStop());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+}
+
+TEST_F(TextRendererTest, TestStopPending2RemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnStop());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+}
+
+TEST_F(TextRendererTest, PlayPauseRemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayPauseRemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayPause2RemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ AbortPendingReads();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayPause2RemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayPause2RemoveC) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayPause2RemoveD) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPausePendingRemove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPausePending2RemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPausePending2RemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCuePausePendingRemove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ SendCues(true);
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCuePausePending2RemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCue(0, true);
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ SendCue(1, true);
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCuePausePending2RemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCue(0, true);
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ SendCue(1, true);
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPauseRemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPauseRemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2ARemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2ARemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2ARemoveC) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2ARemoveD) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2BRemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2BRemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2BRemoveC) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosPause2BRemoveD) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosFlushRemove) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnFlush());
+ text_renderer_->Flush(base::Bind(&TextRendererTest::OnFlush,
+ base::Unretained(this)));
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosFlush2RemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnFlush());
+ text_renderer_->Flush(base::Bind(&TextRendererTest::OnFlush,
+ base::Unretained(this)));
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayEosFlush2RemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ SendEosNotifications();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnFlush());
+ text_renderer_->Flush(base::Bind(&TextRendererTest::OnFlush,
+ base::Unretained(this)));
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayShort2A) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCue(0, true);
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayShort2B) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ SendCue(1, true);
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayShort2RemoveA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCue(0, true);
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayShort2RemoveB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCue(0, true);
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ EXPECT_FALSE(text_tracks_[0]);
+ EXPECT_TRUE(text_renderer_->HasTracks());
+
+ EXPECT_CALL(*this, OnPause());
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_2);
+ EXPECT_FALSE(text_tracks_[1]);
+ EXPECT_FALSE(text_renderer_->HasTracks());
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCuePausePendingCancel) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_stream->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCuePausePending2CancelA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCue(0, true);
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCuePausePending2CancelB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ SendCue(1, true);
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, PlayCueStopPendingCancel) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*this, OnPlay());
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnStop());
+ text_stream->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+}
+
+TEST_F(TextRendererTest, PlayCueStopPending2CancelA) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ SendCue(0, false);
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnStop());
+ text_stream_2->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+}
+
+TEST_F(TextRendererTest, PlayCueStopPending2CancelB) {
+ CreateTextRenderer();
+
+ TextTrackStream* const text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* const text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnStop());
+ SendCue(1, false);
+ message_loop_.RunUntilIdle();
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+}
+
+TEST_F(TextRendererTest, AddRemoveAdd) {
+ CreateTextRenderer();
+
+ TextTrackStream* text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream);
+ text_track_streams_.clear();
+
+ EXPECT_CALL(*this, OnPause());
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "", "");
+
+ EXPECT_CALL(*text_stream, Read(_))
+ .WillOnce(Invoke(text_stream, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddRemoveAdd2A) {
+ CreateTextRenderer();
+
+ TextTrackStream* text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ text_track_streams_.erase(text_track_streams_.begin());
+
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddRemoveAdd2B) {
+ CreateTextRenderer();
+
+ TextTrackStream* text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ text_track_streams_.erase(text_track_streams_.begin());
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnPause());
+ EXPECT_CALL(*this, OnEnd());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ DestroyTextRenderer();
+}
+
+TEST_F(TextRendererTest, AddRemoveAdd2C) {
+ CreateTextRenderer();
+
+ TextTrackStream* text_stream_1 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "1", "");
+
+ EXPECT_CALL(*text_stream_1, Read(_))
+ .WillOnce(Invoke(text_stream_1, &TextTrackStream::DoRead));
+
+ TextTrackStream* text_stream_2 = CreateTextTrack();
+ AddTextTrack(kTextSubtitles, "2", "");
+
+ EXPECT_CALL(*text_stream_2, Read(_))
+ .WillOnce(Invoke(text_stream_2, &TextTrackStream::DoRead));
+
+ EXPECT_CALL(*this, OnPlay());
+
+ text_renderer_->Play(base::Bind(&TextRendererTest::OnPlay,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_stream_1->AbortPendingRead();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->RemoveTextStream(text_stream_1);
+ text_track_streams_.erase(text_track_streams_.begin());
+
+ text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ text_renderer_->Stop(base::Bind(&TextRendererTest::OnStop,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+
+ EXPECT_CALL(*this, OnStop());
+ text_stream_2->SendEosNotification();
+ message_loop_.RunUntilIdle();
+
+ text_renderer_.reset();
+ text_track_streams_.clear();
+}
+
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698