1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <vector>
6
7#include "base/bind.h"
8#include "base/callback_helpers.h"
9#include "base/memory/scoped_vector.h"
10#include "base/message_loop/message_loop.h"
11#include "media/base/audio_decoder_config.h"
12#include "media/base/decoder_buffer.h"
13#include "media/base/demuxer_stream.h"
14#include "media/base/fake_text_track_stream.h"
15#include "media/base/text_renderer.h"
16#include "media/base/text_track_config.h"
17#include "media/base/video_decoder_config.h"
18#include "media/filters/webvtt_util.h"
19#include "testing/gmock/include/gmock/gmock.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
22namespace media {
23
24// Local implementation of the TextTrack interface.
25class FakeTextTrack : public TextTrack {
26 public:
27  FakeTextTrack(const base::Closure& destroy_cb,
28                const TextTrackConfig& config)
29      : destroy_cb_(destroy_cb),
30        config_(config) {
31  }
32  virtual ~FakeTextTrack() {
33    destroy_cb_.Run();
34  }
35
36  MOCK_METHOD5(addWebVTTCue, void(const base::TimeDelta& start,
37                                  const base::TimeDelta& end,
38                                  const std::string& id,
39                                  const std::string& content,
40                                  const std::string& settings));
41
42  const base::Closure destroy_cb_;
43  const TextTrackConfig config_;
44
45 private:
46  DISALLOW_COPY_AND_ASSIGN(FakeTextTrack);
47};
48
49class TextRendererTest : public testing::Test {
50 public:
51  TextRendererTest() {}
52
53  void CreateTextRenderer() {
54    DCHECK(!text_renderer_);
55
56    text_renderer_.reset(
57        new TextRenderer(message_loop_.message_loop_proxy(),
58                         base::Bind(&TextRendererTest::OnAddTextTrack,
59                                    base::Unretained(this))));
60    text_renderer_->Initialize(base::Bind(&TextRendererTest::OnEnd,
61                                          base::Unretained(this)));
62  }
63
64  void Destroy() {
65    text_renderer_.reset();
66    message_loop_.RunUntilIdle();
67  }
68
69  void AddTextTrack(TextKind kind,
70                    const std::string& name,
71                    const std::string& language,
72                    bool expect_read) {
73    const size_t idx = text_track_streams_.size();
74    text_track_streams_.push_back(new FakeTextTrackStream);
75
76    if (expect_read)
77      ExpectRead(idx);
78
79    const TextTrackConfig config(kind, name, language, std::string());
80    text_renderer_->AddTextStream(text_track_streams_.back(), config);
81    message_loop_.RunUntilIdle();
82
83    EXPECT_EQ(text_tracks_.size(), text_track_streams_.size());
84    FakeTextTrack* const text_track = text_tracks_.back();
85    EXPECT_TRUE(text_track);
86    EXPECT_TRUE(text_track->config_.Matches(config));
87  }
88
89  void OnAddTextTrack(const TextTrackConfig& config,
90                      const AddTextTrackDoneCB& done_cb) {
91    base::Closure destroy_cb =
92        base::Bind(&TextRendererTest::OnDestroyTextTrack,
93                   base::Unretained(this),
94                   text_tracks_.size());
95    // Text track objects are owned by the text renderer, but we cache them
96    // here so we can inspect them.  They get removed from our cache when the
97    // text renderer deallocates them.
98    text_tracks_.push_back(new FakeTextTrack(destroy_cb, config));
99    scoped_ptr<TextTrack> text_track(text_tracks_.back());
100    done_cb.Run(text_track.Pass());
101  }
102
103  void RemoveTextTrack(unsigned idx) {
104    FakeTextTrackStream* const stream = text_track_streams_[idx];
105    text_renderer_->RemoveTextStream(stream);
106    EXPECT_FALSE(text_tracks_[idx]);
107  }
108
109  void SatisfyPendingReads(const base::TimeDelta& start,
110                           const base::TimeDelta& duration,
111                           const std::string& id,
112                           const std::string& content,
113                           const std::string& settings) {
114    for (TextTrackStreams::iterator itr = text_track_streams_.begin();
115         itr != text_track_streams_.end(); ++itr) {
116      (*itr)->SatisfyPendingRead(start, duration, id, content, settings);
117    }
118  }
119
120  void AbortPendingRead(unsigned idx) {
121    FakeTextTrackStream* const stream = text_track_streams_[idx];
122    stream->AbortPendingRead();
123    message_loop_.RunUntilIdle();
124  }
125
126  void AbortPendingReads() {
127    for (size_t idx = 0; idx < text_track_streams_.size(); ++idx) {
128      AbortPendingRead(idx);
129    }
130  }
131
132  void SendEosNotification(unsigned idx) {
133    FakeTextTrackStream* const stream = text_track_streams_[idx];
134    stream->SendEosNotification();
135    message_loop_.RunUntilIdle();
136  }
137
138  void SendEosNotifications() {
139    for (size_t idx = 0; idx < text_track_streams_.size(); ++idx) {
140      SendEosNotification(idx);
141    }
142  }
143
144  void SendCue(unsigned idx, bool expect_cue) {
145    FakeTextTrackStream* const text_stream = text_track_streams_[idx];
146
147    const base::TimeDelta start;
148    const base::TimeDelta duration = base::TimeDelta::FromSeconds(42);
149    const std::string id = "id";
150    const std::string content = "subtitle";
151    const std::string settings;
152
153    if (expect_cue) {
154      FakeTextTrack* const text_track = text_tracks_[idx];
155      EXPECT_CALL(*text_track, addWebVTTCue(start,
156                                            start + duration,
157                                            id,
158                                            content,
159                                            settings));
160    }
161
162    text_stream->SatisfyPendingRead(start, duration, id, content, settings);
163    message_loop_.RunUntilIdle();
164  }
165
166  void SendCues(bool expect_cue) {
167    for (size_t idx = 0; idx < text_track_streams_.size(); ++idx) {
168      SendCue(idx, expect_cue);
169    }
170  }
171
172  void OnDestroyTextTrack(unsigned idx) {
173    text_tracks_[idx] = NULL;
174  }
175
176  void Play() {
177    text_renderer_->StartPlaying();
178  }
179
180  void Pause() {
181    text_renderer_->Pause(base::Bind(&TextRendererTest::OnPause,
182                                     base::Unretained(this)));
183    message_loop_.RunUntilIdle();
184  }
185
186  void Flush() {
187    EXPECT_CALL(*this, OnFlush());
188    text_renderer_->Flush(base::Bind(&TextRendererTest::OnFlush,
189                                     base::Unretained(this)));
190  }
191
192  void ExpectRead(size_t idx) {
193    FakeTextTrackStream* const stream = text_track_streams_[idx];
194    EXPECT_CALL(*stream, OnRead());
195  }
196
197  MOCK_METHOD0(OnEnd, void());
198  MOCK_METHOD0(OnPause, void());
199  MOCK_METHOD0(OnFlush, void());
200
201  base::MessageLoop message_loop_;
202
203  typedef ScopedVector<FakeTextTrackStream> TextTrackStreams;
204  TextTrackStreams text_track_streams_;
205
206  typedef std::vector<FakeTextTrack*> TextTracks;
207  TextTracks text_tracks_;
208
209  scoped_ptr<TextRenderer> text_renderer_;
210
211 private:
212  DISALLOW_COPY_AND_ASSIGN(TextRendererTest);
213};
214
215TEST_F(TextRendererTest, CreateTextRendererNoInit) {
216  text_renderer_.reset(
217      new TextRenderer(message_loop_.message_loop_proxy(),
218                       base::Bind(&TextRendererTest::OnAddTextTrack,
219                                  base::Unretained(this))));
220  text_renderer_.reset();
221}
222
223TEST_F(TextRendererTest, Create) {
224  CreateTextRenderer();
225}
226
227TEST_F(TextRendererTest, AddTextTrackOnly_OneTrack) {
228  CreateTextRenderer();
229  AddTextTrack(kTextSubtitles, "", "", false);
230}
231
232TEST_F(TextRendererTest, AddTextTrackOnly_TwoTracks) {
233  CreateTextRenderer();
234  AddTextTrack(kTextSubtitles, "track 1", "", false);
235  AddTextTrack(kTextSubtitles, "track 2", "", false);
236}
237
238TEST_F(TextRendererTest, PlayOnly) {
239  CreateTextRenderer();
240  Play();
241}
242
243TEST_F(TextRendererTest, AddTrackBeforePlay_OneTrack) {
244  CreateTextRenderer();
245  AddTextTrack(kTextSubtitles, "", "", true);
246  Play();
247  AbortPendingReads();
248}
249
250TEST_F(TextRendererTest, AddTrackBeforePlay_TwoTracks) {
251  CreateTextRenderer();
252  AddTextTrack(kTextSubtitles, "1", "", true);
253  AddTextTrack(kTextSubtitles, "2", "", true);
254  Play();
255  AbortPendingReads();
256}
257
258TEST_F(TextRendererTest, AddTrackAfterPlay_OneTrackAfter) {
259  CreateTextRenderer();
260  Play();
261  AddTextTrack(kTextSubtitles, "", "", true);
262  AbortPendingReads();
263}
264
265TEST_F(TextRendererTest, AddTrackAfterPlay_TwoTracksAfter) {
266  CreateTextRenderer();
267  Play();
268  AddTextTrack(kTextSubtitles, "1", "", true);
269  AddTextTrack(kTextSubtitles, "2", "", true);
270  AbortPendingReads();
271}
272
273TEST_F(TextRendererTest, AddTrackAfterPlay_OneTrackBeforeOneTrackAfter) {
274  CreateTextRenderer();
275  AddTextTrack(kTextSubtitles, "1", "", true);
276  Play();
277  AddTextTrack(kTextSubtitles, "2", "", true);
278  AbortPendingReads();
279}
280
281TEST_F(TextRendererTest, PlayAddCue_OneTrack) {
282  CreateTextRenderer();
283  AddTextTrack(kTextSubtitles, "", "", true);
284  Play();
285  ExpectRead(0);
286  SendCues(true);
287  AbortPendingReads();
288}
289
290TEST_F(TextRendererTest, PlayAddCue_TwoTracks) {
291  CreateTextRenderer();
292  AddTextTrack(kTextSubtitles, "1", "", true);
293  AddTextTrack(kTextSubtitles, "2", "", true);
294  Play();
295  ExpectRead(0);
296  ExpectRead(1);
297  SendCues(true);
298  AbortPendingReads();
299}
300
301TEST_F(TextRendererTest, PlayEosOnly_OneTrack) {
302  CreateTextRenderer();
303  AddTextTrack(kTextSubtitles, "", "", true);
304  Play();
305  EXPECT_CALL(*this, OnEnd());
306  SendEosNotifications();
307}
308
309TEST_F(TextRendererTest, PlayEosOnly_TwoTracks) {
310  CreateTextRenderer();
311  AddTextTrack(kTextSubtitles, "1", "", true);
312  AddTextTrack(kTextSubtitles, "2", "", true);
313  Play();
314  EXPECT_CALL(*this, OnEnd());
315  SendEosNotifications();
316}
317
318TEST_F(TextRendererTest, PlayCueEos_OneTrack) {
319  CreateTextRenderer();
320  AddTextTrack(kTextSubtitles, "", "", true);
321  Play();
322  ExpectRead(0);
323  SendCues(true);
324  EXPECT_CALL(*this, OnEnd());
325  SendEosNotifications();
326}
327
328TEST_F(TextRendererTest, PlayCueEos_TwoTracks) {
329  CreateTextRenderer();
330  AddTextTrack(kTextSubtitles, "1", "", true);
331  AddTextTrack(kTextSubtitles, "2", "", true);
332  Play();
333  ExpectRead(0);
334  ExpectRead(1);
335  SendCues(true);
336  EXPECT_CALL(*this, OnEnd());
337  SendEosNotifications();
338}
339
340TEST_F(TextRendererTest, DestroyPending_OneTrack) {
341  CreateTextRenderer();
342  AddTextTrack(kTextSubtitles, "", "", true);
343  Play();
344  Destroy();
345  SendEosNotifications();
346}
347
348TEST_F(TextRendererTest, DestroyPending_TwoTracks) {
349  CreateTextRenderer();
350  AddTextTrack(kTextSubtitles, "1", "", true);
351  AddTextTrack(kTextSubtitles, "2", "", true);
352  Play();
353  Destroy();
354  SendEosNotifications();
355}
356
357TEST_F(TextRendererTest, PlayPause_OneTrack) {
358  CreateTextRenderer();
359  AddTextTrack(kTextSubtitles, "", "", true);
360  Play();
361  AbortPendingReads();
362  EXPECT_CALL(*this, OnPause());
363  Pause();
364}
365
366TEST_F(TextRendererTest, PlayPause_TwoTracks) {
367  CreateTextRenderer();
368  AddTextTrack(kTextSubtitles, "1", "", true);
369  AddTextTrack(kTextSubtitles, "2", "", true);
370  Play();
371  AbortPendingReads();
372  EXPECT_CALL(*this, OnPause());
373  Pause();
374}
375
376TEST_F(TextRendererTest, PlayEosPausePending_OneTrack) {
377  CreateTextRenderer();
378  AddTextTrack(kTextSubtitles, "", "", true);
379  Play();
380  Pause();
381  EXPECT_CALL(*this, OnPause());
382  SendEosNotifications();
383}
384
385TEST_F(TextRendererTest, PlayEosPausePending_TwoTracks) {
386  CreateTextRenderer();
387  AddTextTrack(kTextSubtitles, "1", "", true);
388  AddTextTrack(kTextSubtitles, "2", "", true);
389  Play();
390  Pause();
391  EXPECT_CALL(*this, OnPause());
392  SendEosNotifications();
393}
394
395TEST_F(TextRendererTest, PlayCuePausePending_OneTrack) {
396  CreateTextRenderer();
397  AddTextTrack(kTextSubtitles, "", "", true);
398  Play();
399  Pause();
400  EXPECT_CALL(*this, OnPause());
401  SendCues(true);
402}
403
404TEST_F(TextRendererTest, PlayCuePausePending_TwoTracks) {
405  CreateTextRenderer();
406  AddTextTrack(kTextSubtitles, "1", "", true);
407  AddTextTrack(kTextSubtitles, "2", "", true);
408  Play();
409  Pause();
410  EXPECT_CALL(*this, OnPause());
411  SendCues(true);
412}
413
414TEST_F(TextRendererTest, PlayEosPause_OneTrack) {
415  CreateTextRenderer();
416  AddTextTrack(kTextSubtitles, "", "", true);
417  Play();
418  EXPECT_CALL(*this, OnEnd());
419  SendEosNotifications();
420  EXPECT_CALL(*this, OnPause());
421  Pause();
422}
423
424TEST_F(TextRendererTest, PlayEosPause_TwoTracks) {
425  CreateTextRenderer();
426  AddTextTrack(kTextSubtitles, "1", "", true);
427  AddTextTrack(kTextSubtitles, "2", "", true);
428  Play();
429  EXPECT_CALL(*this, OnEnd());
430  SendEosNotifications();
431  EXPECT_CALL(*this, OnPause());
432  Pause();
433}
434
435TEST_F(TextRendererTest, PlayEosPause_SplitEos) {
436  CreateTextRenderer();
437  AddTextTrack(kTextSubtitles, "1", "", true);
438  AddTextTrack(kTextSubtitles, "2", "", true);
439  Play();
440  SendEosNotification(0);
441  EXPECT_CALL(*this, OnEnd());
442  SendEosNotification(1);
443  EXPECT_CALL(*this, OnPause());
444  Pause();
445}
446
447TEST_F(TextRendererTest, PlayEosFlush_OneTrack) {
448  CreateTextRenderer();
449  AddTextTrack(kTextSubtitles, "", "", true);
450  Play();
451  EXPECT_CALL(*this, OnEnd());
452  SendEosNotifications();
453  EXPECT_CALL(*this, OnPause());
454  Pause();
455  Flush();
456  ExpectRead(0);
457  Play();
458  EXPECT_CALL(*this, OnEnd());
459  SendEosNotifications();
460}
461
462TEST_F(TextRendererTest, PlayEosFlush_TwoTracks) {
463  CreateTextRenderer();
464  AddTextTrack(kTextSubtitles, "1", "", true);
465  AddTextTrack(kTextSubtitles, "2", "", true);
466  Play();
467  EXPECT_CALL(*this, OnEnd());
468  SendEosNotifications();
469  EXPECT_CALL(*this, OnPause());
470  Pause();
471  Flush();
472  ExpectRead(0);
473  ExpectRead(1);
474  Play();
475  EXPECT_CALL(*this, OnEnd());
476  SendEosNotifications();
477}
478
479TEST_F(TextRendererTest, AddTextTrackOnlyRemove_OneTrack) {
480  CreateTextRenderer();
481  AddTextTrack(kTextSubtitles, "", "", false);
482  EXPECT_TRUE(text_renderer_->HasTracks());
483}
484
485TEST_F(TextRendererTest, AddTextTrackOnlyRemove_TwoTracks) {
486  CreateTextRenderer();
487  AddTextTrack(kTextSubtitles, "track 1", "", false);
488  AddTextTrack(kTextSubtitles, "track 2", "", false);
489  RemoveTextTrack(0);
490  EXPECT_TRUE(text_renderer_->HasTracks());
491  RemoveTextTrack(1);
492  EXPECT_FALSE(text_renderer_->HasTracks());
493}
494
495TEST_F(TextRendererTest, AddTrackBeforePlayRemove_OneTrack) {
496  CreateTextRenderer();
497  AddTextTrack(kTextSubtitles, "", "", true);
498  Play();
499  AbortPendingReads();
500  RemoveTextTrack(0);
501  EXPECT_FALSE(text_renderer_->HasTracks());
502}
503
504TEST_F(TextRendererTest, AddTrackBeforePlayRemove_TwoTracks) {
505  CreateTextRenderer();
506  AddTextTrack(kTextSubtitles, "1", "", true);
507  AddTextTrack(kTextSubtitles, "2", "", true);
508  Play();
509  AbortPendingReads();
510  RemoveTextTrack(0);
511  EXPECT_TRUE(text_renderer_->HasTracks());
512  RemoveTextTrack(1);
513  EXPECT_FALSE(text_renderer_->HasTracks());
514}
515
516TEST_F(TextRendererTest, AddTrackBeforePlayRemove_SeparateCancel) {
517  CreateTextRenderer();
518  AddTextTrack(kTextSubtitles, "1", "", true);
519  AddTextTrack(kTextSubtitles, "2", "", true);
520  Play();
521  AbortPendingRead(0);
522  RemoveTextTrack(0);
523  EXPECT_TRUE(text_renderer_->HasTracks());
524  AbortPendingRead(1);
525  RemoveTextTrack(1);
526  EXPECT_FALSE(text_renderer_->HasTracks());
527}
528
529TEST_F(TextRendererTest, AddTrackBeforePlayRemove_RemoveOneThenPlay) {
530  CreateTextRenderer();
531  AddTextTrack(kTextSubtitles, "1", "", false);
532  AddTextTrack(kTextSubtitles, "2", "", true);
533  RemoveTextTrack(0);
534  EXPECT_TRUE(text_renderer_->HasTracks());
535  Play();
536  AbortPendingRead(1);
537  RemoveTextTrack(1);
538  EXPECT_FALSE(text_renderer_->HasTracks());
539}
540
541TEST_F(TextRendererTest, AddTrackBeforePlayRemove_RemoveTwoThenPlay) {
542  CreateTextRenderer();
543  AddTextTrack(kTextSubtitles, "1", "", false);
544  AddTextTrack(kTextSubtitles, "2", "", false);
545  RemoveTextTrack(0);
546  EXPECT_TRUE(text_renderer_->HasTracks());
547  RemoveTextTrack(1);
548  EXPECT_FALSE(text_renderer_->HasTracks());
549  Play();
550}
551
552TEST_F(TextRendererTest, AddTrackAfterPlayRemove_OneTrack) {
553  CreateTextRenderer();
554  Play();
555  AddTextTrack(kTextSubtitles, "", "", true);
556  AbortPendingReads();
557  RemoveTextTrack(0);
558  EXPECT_FALSE(text_renderer_->HasTracks());
559}
560
561TEST_F(TextRendererTest, AddTrackAfterPlayRemove_TwoTracks) {
562  CreateTextRenderer();
563  Play();
564  AddTextTrack(kTextSubtitles, "1", "", true);
565  AddTextTrack(kTextSubtitles, "2", "", true);
566  AbortPendingReads();
567  RemoveTextTrack(0);
568  EXPECT_TRUE(text_renderer_->HasTracks());
569  RemoveTextTrack(1);
570  EXPECT_FALSE(text_renderer_->HasTracks());
571}
572
573TEST_F(TextRendererTest, AddTrackAfterPlayRemove_SplitCancel) {
574  CreateTextRenderer();
575  Play();
576  AddTextTrack(kTextSubtitles, "1", "", true);
577  AddTextTrack(kTextSubtitles, "2", "", true);
578  AbortPendingRead(0);
579  RemoveTextTrack(0);
580  EXPECT_TRUE(text_renderer_->HasTracks());
581  AbortPendingRead(1);
582  RemoveTextTrack(1);
583  EXPECT_FALSE(text_renderer_->HasTracks());
584}
585
586TEST_F(TextRendererTest, AddTrackAfterPlayRemove_SplitAdd) {
587  CreateTextRenderer();
588  AddTextTrack(kTextSubtitles, "1", "", true);
589  Play();
590  AddTextTrack(kTextSubtitles, "2", "", true);
591  AbortPendingRead(0);
592  RemoveTextTrack(0);
593  EXPECT_TRUE(text_renderer_->HasTracks());
594  AbortPendingRead(1);
595  RemoveTextTrack(1);
596  EXPECT_FALSE(text_renderer_->HasTracks());
597}
598
599TEST_F(TextRendererTest, PlayAddCueRemove_OneTrack) {
600  CreateTextRenderer();
601  AddTextTrack(kTextSubtitles, "", "", true);
602  Play();
603  ExpectRead(0);
604  SendCues(true);
605  AbortPendingReads();
606  RemoveTextTrack(0);
607  EXPECT_FALSE(text_renderer_->HasTracks());
608}
609
610TEST_F(TextRendererTest, PlayAddCueRemove_TwoTracks) {
611  CreateTextRenderer();
612  AddTextTrack(kTextSubtitles, "1", "", true);
613  AddTextTrack(kTextSubtitles, "2", "", true);
614  Play();
615  ExpectRead(0);
616  ExpectRead(1);
617  SendCues(true);
618  AbortPendingRead(0);
619  AbortPendingRead(1);
620  RemoveTextTrack(0);
621  EXPECT_TRUE(text_renderer_->HasTracks());
622  RemoveTextTrack(1);
623  EXPECT_FALSE(text_renderer_->HasTracks());
624}
625
626TEST_F(TextRendererTest, PlayEosOnlyRemove_OneTrack) {
627  CreateTextRenderer();
628  AddTextTrack(kTextSubtitles, "", "", true);
629  Play();
630  EXPECT_CALL(*this, OnEnd());
631  SendEosNotifications();
632  RemoveTextTrack(0);
633  EXPECT_FALSE(text_renderer_->HasTracks());
634}
635
636TEST_F(TextRendererTest, PlayEosOnlyRemove_TwoTracks) {
637  CreateTextRenderer();
638  AddTextTrack(kTextSubtitles, "1", "", true);
639  AddTextTrack(kTextSubtitles, "2", "", true);
640  Play();
641  EXPECT_CALL(*this, OnEnd());
642  SendEosNotifications();
643  RemoveTextTrack(0);
644  EXPECT_TRUE(text_renderer_->HasTracks());
645  RemoveTextTrack(1);
646  EXPECT_FALSE(text_renderer_->HasTracks());
647}
648
649TEST_F(TextRendererTest, PlayCueEosRemove_OneTrack) {
650  CreateTextRenderer();
651  AddTextTrack(kTextSubtitles, "", "", true);
652  Play();
653  ExpectRead(0);
654  SendCues(true);
655  EXPECT_CALL(*this, OnEnd());
656  SendEosNotifications();
657  RemoveTextTrack(0);
658  EXPECT_FALSE(text_renderer_->HasTracks());
659}
660
661TEST_F(TextRendererTest, PlayCueEosRemove_TwoTracks) {
662  CreateTextRenderer();
663  AddTextTrack(kTextSubtitles, "1", "", true);
664  AddTextTrack(kTextSubtitles, "2", "", true);
665  Play();
666  ExpectRead(0);
667  ExpectRead(1);
668  SendCues(true);
669  EXPECT_CALL(*this, OnEnd());
670  SendEosNotifications();
671  RemoveTextTrack(0);
672  EXPECT_TRUE(text_renderer_->HasTracks());
673  RemoveTextTrack(1);
674  EXPECT_FALSE(text_renderer_->HasTracks());
675}
676
677TEST_F(TextRendererTest, PlayPauseRemove_PauseThenRemove) {
678  CreateTextRenderer();
679  AddTextTrack(kTextSubtitles, "", "", true);
680  Play();
681  AbortPendingReads();
682  EXPECT_CALL(*this, OnPause());
683  Pause();
684  RemoveTextTrack(0);
685  EXPECT_FALSE(text_renderer_->HasTracks());
686}
687
688TEST_F(TextRendererTest, PlayPauseRemove_RemoveThanPause) {
689  CreateTextRenderer();
690  AddTextTrack(kTextSubtitles, "", "", true);
691  Play();
692  AbortPendingReads();
693  RemoveTextTrack(0);
694  EXPECT_FALSE(text_renderer_->HasTracks());
695  EXPECT_CALL(*this, OnPause());
696  Pause();
697}
698
699TEST_F(TextRendererTest, PlayPause_PauseThenRemoveTwoTracks) {
700  CreateTextRenderer();
701  AddTextTrack(kTextSubtitles, "1", "", true);
702  AddTextTrack(kTextSubtitles, "2", "", true);
703  Play();
704  AbortPendingReads();
705  EXPECT_CALL(*this, OnPause());
706  Pause();
707  RemoveTextTrack(0);
708  EXPECT_TRUE(text_renderer_->HasTracks());
709  RemoveTextTrack(1);
710  EXPECT_FALSE(text_renderer_->HasTracks());
711}
712
713TEST_F(TextRendererTest, PlayPauseRemove_RemoveThenPauseTwoTracks) {
714  CreateTextRenderer();
715  AddTextTrack(kTextSubtitles, "1", "", true);
716  AddTextTrack(kTextSubtitles, "2", "", true);
717  Play();
718  AbortPendingReads();
719  RemoveTextTrack(0);
720  EXPECT_TRUE(text_renderer_->HasTracks());
721  EXPECT_CALL(*this, OnPause());
722  Pause();
723  RemoveTextTrack(1);
724  EXPECT_FALSE(text_renderer_->HasTracks());
725}
726
727TEST_F(TextRendererTest, PlayPauseRemove_SplitCancel) {
728  CreateTextRenderer();
729  AddTextTrack(kTextSubtitles, "1", "", true);
730  AddTextTrack(kTextSubtitles, "2", "", true);
731  Play();
732  AbortPendingRead(0);
733  RemoveTextTrack(0);
734  EXPECT_TRUE(text_renderer_->HasTracks());
735  AbortPendingRead(1);
736  EXPECT_CALL(*this, OnPause());
737  Pause();
738  RemoveTextTrack(1);
739  EXPECT_FALSE(text_renderer_->HasTracks());
740}
741
742
743TEST_F(TextRendererTest, PlayPauseRemove_PauseLast) {
744  CreateTextRenderer();
745  AddTextTrack(kTextSubtitles, "1", "", true);
746  AddTextTrack(kTextSubtitles, "2", "", true);
747  Play();
748  AbortPendingRead(0);
749  RemoveTextTrack(0);
750  EXPECT_TRUE(text_renderer_->HasTracks());
751  AbortPendingRead(1);
752  RemoveTextTrack(1);
753  EXPECT_FALSE(text_renderer_->HasTracks());
754  EXPECT_CALL(*this, OnPause());
755  Pause();
756}
757
758TEST_F(TextRendererTest, PlayEosPausePendingRemove_OneTrack) {
759  CreateTextRenderer();
760  AddTextTrack(kTextSubtitles, "", "", true);
761  Play();
762  Pause();
763  EXPECT_CALL(*this, OnPause());
764  SendEosNotifications();
765  RemoveTextTrack(0);
766  EXPECT_FALSE(text_renderer_->HasTracks());
767}
768
769TEST_F(TextRendererTest, PlayEosPausePendingRemove_TwoTracks) {
770  CreateTextRenderer();
771  AddTextTrack(kTextSubtitles, "1", "", true);
772  AddTextTrack(kTextSubtitles, "2", "", true);
773  Play();
774  Pause();
775  SendEosNotification(0);
776  EXPECT_CALL(*this, OnPause());
777  SendEosNotification(1);
778  RemoveTextTrack(0);
779  EXPECT_TRUE(text_renderer_->HasTracks());
780  RemoveTextTrack(1);
781  EXPECT_FALSE(text_renderer_->HasTracks());
782}
783
784TEST_F(TextRendererTest, PlayEosPausePendingRemove_SplitEos) {
785  CreateTextRenderer();
786  AddTextTrack(kTextSubtitles, "1", "", true);
787  AddTextTrack(kTextSubtitles, "2", "", true);
788  Play();
789  Pause();
790  SendEosNotification(0);
791  RemoveTextTrack(0);
792  EXPECT_TRUE(text_renderer_->HasTracks());
793  EXPECT_CALL(*this, OnPause());
794  SendEosNotification(1);
795  RemoveTextTrack(1);
796  EXPECT_FALSE(text_renderer_->HasTracks());
797}
798
799TEST_F(TextRendererTest, PlayCuePausePendingRemove_OneTrack) {
800  CreateTextRenderer();
801  AddTextTrack(kTextSubtitles, "", "", true);
802  Play();
803  Pause();
804  EXPECT_CALL(*this, OnPause());
805  SendCues(true);
806  RemoveTextTrack(0);
807  EXPECT_FALSE(text_renderer_->HasTracks());
808}
809
810TEST_F(TextRendererTest, PlayCuePausePendingRemove_TwoTracks) {
811  CreateTextRenderer();
812  AddTextTrack(kTextSubtitles, "1", "", true);
813  AddTextTrack(kTextSubtitles, "2", "", true);
814  Play();
815  Pause();
816  SendCue(0, true);
817  EXPECT_CALL(*this, OnPause());
818  SendCue(1, true);
819  RemoveTextTrack(0);
820  EXPECT_TRUE(text_renderer_->HasTracks());
821  RemoveTextTrack(1);
822  EXPECT_FALSE(text_renderer_->HasTracks());
823}
824
825TEST_F(TextRendererTest, PlayCuePausePendingRemove_SplitSendCue) {
826  CreateTextRenderer();
827  AddTextTrack(kTextSubtitles, "1", "", true);
828  AddTextTrack(kTextSubtitles, "2", "", true);
829  Play();
830  Pause();
831  SendCue(0, true);
832  RemoveTextTrack(0);
833  EXPECT_TRUE(text_renderer_->HasTracks());
834  EXPECT_CALL(*this, OnPause());
835  SendCue(1, true);
836  RemoveTextTrack(1);
837  EXPECT_FALSE(text_renderer_->HasTracks());
838}
839
840TEST_F(TextRendererTest, PlayEosPauseRemove_PauseThenRemove) {
841  CreateTextRenderer();
842  AddTextTrack(kTextSubtitles, "", "", true);
843  Play();
844  EXPECT_CALL(*this, OnEnd());
845  SendEosNotifications();
846  EXPECT_CALL(*this, OnPause());
847  Pause();
848  RemoveTextTrack(0);
849  EXPECT_FALSE(text_renderer_->HasTracks());
850}
851
852TEST_F(TextRendererTest, PlayEosPauseRemove_RemoveThenPause) {
853  CreateTextRenderer();
854  AddTextTrack(kTextSubtitles, "", "", true);
855  Play();
856  EXPECT_CALL(*this, OnEnd());
857  SendEosNotifications();
858  RemoveTextTrack(0);
859  EXPECT_FALSE(text_renderer_->HasTracks());
860  EXPECT_CALL(*this, OnPause());
861  Pause();
862}
863
864TEST_F(TextRendererTest, PlayEosPause_PauseThenRemoveTwoTracks) {
865  CreateTextRenderer();
866  AddTextTrack(kTextSubtitles, "1", "", true);
867  AddTextTrack(kTextSubtitles, "2", "", true);
868  Play();
869  SendEosNotification(0);
870  EXPECT_CALL(*this, OnEnd());
871  SendEosNotification(1);
872  EXPECT_CALL(*this, OnPause());
873  Pause();
874  RemoveTextTrack(0);
875  EXPECT_TRUE(text_renderer_->HasTracks());
876  RemoveTextTrack(1);
877  EXPECT_FALSE(text_renderer_->HasTracks());
878}
879
880TEST_F(TextRendererTest, PlayEosPause_RemovePauseRemove) {
881  CreateTextRenderer();
882  AddTextTrack(kTextSubtitles, "1", "", true);
883  AddTextTrack(kTextSubtitles, "2", "", true);
884  Play();
885  SendEosNotification(0);
886  EXPECT_CALL(*this, OnEnd());
887  SendEosNotification(1);
888  RemoveTextTrack(0);
889  EXPECT_TRUE(text_renderer_->HasTracks());
890  EXPECT_CALL(*this, OnPause());
891  Pause();
892  RemoveTextTrack(1);
893  EXPECT_FALSE(text_renderer_->HasTracks());
894}
895
896TEST_F(TextRendererTest, PlayEosPause_EosThenPause) {
897  CreateTextRenderer();
898  AddTextTrack(kTextSubtitles, "1", "", true);
899  AddTextTrack(kTextSubtitles, "2", "", true);
900  Play();
901  SendEosNotification(0);
902  RemoveTextTrack(0);
903  EXPECT_TRUE(text_renderer_->HasTracks());
904  EXPECT_CALL(*this, OnEnd());
905  SendEosNotification(1);
906  EXPECT_CALL(*this, OnPause());
907  Pause();
908  RemoveTextTrack(1);
909  EXPECT_FALSE(text_renderer_->HasTracks());
910}
911
912TEST_F(TextRendererTest, PlayEosPause_PauseLast) {
913  CreateTextRenderer();
914  AddTextTrack(kTextSubtitles, "1", "", true);
915  AddTextTrack(kTextSubtitles, "2", "", true);
916  Play();
917  SendEosNotification(0);
918  RemoveTextTrack(0);
919  EXPECT_TRUE(text_renderer_->HasTracks());
920  EXPECT_CALL(*this, OnEnd());
921  SendEosNotification(1);
922  RemoveTextTrack(1);
923  EXPECT_FALSE(text_renderer_->HasTracks());
924  EXPECT_CALL(*this, OnPause());
925  Pause();
926}
927
928TEST_F(TextRendererTest, PlayEosPause_EosPauseRemove) {
929  CreateTextRenderer();
930  AddTextTrack(kTextSubtitles, "1", "", true);
931  AddTextTrack(kTextSubtitles, "2", "", true);
932  Play();
933  SendEosNotification(0);
934  EXPECT_CALL(*this, OnEnd());
935  SendEosNotification(1);
936  EXPECT_CALL(*this, OnPause());
937  Pause();
938  RemoveTextTrack(0);
939  EXPECT_TRUE(text_renderer_->HasTracks());
940  RemoveTextTrack(1);
941  EXPECT_FALSE(text_renderer_->HasTracks());
942}
943
944TEST_F(TextRendererTest, PlayEosPause_EosRemovePause) {
945  CreateTextRenderer();
946  AddTextTrack(kTextSubtitles, "1", "", true);
947  AddTextTrack(kTextSubtitles, "2", "", true);
948  Play();
949  SendEosNotification(0);
950  EXPECT_CALL(*this, OnEnd());
951  SendEosNotification(1);
952  RemoveTextTrack(0);
953  EXPECT_TRUE(text_renderer_->HasTracks());
954  EXPECT_CALL(*this, OnPause());
955  Pause();
956  RemoveTextTrack(1);
957  EXPECT_FALSE(text_renderer_->HasTracks());
958}
959
960TEST_F(TextRendererTest, PlayEosPause_EosRemoveEosPause) {
961  CreateTextRenderer();
962  AddTextTrack(kTextSubtitles, "1", "", true);
963  AddTextTrack(kTextSubtitles, "2", "", true);
964  Play();
965  SendEosNotification(0);
966  RemoveTextTrack(0);
967  EXPECT_TRUE(text_renderer_->HasTracks());
968  EXPECT_CALL(*this, OnEnd());
969  SendEosNotification(1);
970  EXPECT_CALL(*this, OnPause());
971  Pause();
972  RemoveTextTrack(1);
973  EXPECT_FALSE(text_renderer_->HasTracks());
974}
975
976TEST_F(TextRendererTest, PlayEosPause_EosRemoveEosRemovePause) {
977  CreateTextRenderer();
978  AddTextTrack(kTextSubtitles, "1", "", true);
979  AddTextTrack(kTextSubtitles, "2", "", true);
980  Play();
981  SendEosNotification(0);
982  RemoveTextTrack(0);
983  EXPECT_TRUE(text_renderer_->HasTracks());
984  EXPECT_CALL(*this, OnEnd());
985  SendEosNotification(1);
986  RemoveTextTrack(1);
987  EXPECT_FALSE(text_renderer_->HasTracks());
988  EXPECT_CALL(*this, OnPause());
989  Pause();
990}
991
992TEST_F(TextRendererTest, PlayEosFlushRemove_OneTrack) {
993  CreateTextRenderer();
994  AddTextTrack(kTextSubtitles, "", "", true);
995  Play();
996  EXPECT_CALL(*this, OnEnd());
997  SendEosNotifications();
998  EXPECT_CALL(*this, OnPause());
999  Pause();
1000  Flush();
1001  ExpectRead(0);
1002  Play();
1003  EXPECT_CALL(*this, OnEnd());
1004  SendEosNotifications();
1005  RemoveTextTrack(0);
1006  EXPECT_FALSE(text_renderer_->HasTracks());
1007}
1008
1009TEST_F(TextRendererTest, PlayEosFlushRemove_TwoTracks) {
1010  CreateTextRenderer();
1011  AddTextTrack(kTextSubtitles, "1", "", true);
1012  AddTextTrack(kTextSubtitles, "2", "", true);
1013  Play();
1014  EXPECT_CALL(*this, OnEnd());
1015  SendEosNotifications();
1016  EXPECT_CALL(*this, OnPause());
1017  Pause();
1018  Flush();
1019  ExpectRead(0);
1020  ExpectRead(1);
1021  Play();
1022  SendEosNotification(0);
1023  EXPECT_CALL(*this, OnEnd());
1024  SendEosNotification(1);
1025  RemoveTextTrack(0);
1026  EXPECT_TRUE(text_renderer_->HasTracks());
1027  RemoveTextTrack(1);
1028  EXPECT_FALSE(text_renderer_->HasTracks());
1029}
1030
1031TEST_F(TextRendererTest, PlayEosFlushRemove_EosRemove) {
1032  CreateTextRenderer();
1033  AddTextTrack(kTextSubtitles, "1", "", true);
1034  AddTextTrack(kTextSubtitles, "2", "", true);
1035  Play();
1036  EXPECT_CALL(*this, OnEnd());
1037  SendEosNotifications();
1038  EXPECT_CALL(*this, OnPause());
1039  Pause();
1040  Flush();
1041  ExpectRead(0);
1042  ExpectRead(1);
1043  Play();
1044  SendEosNotification(0);
1045  RemoveTextTrack(0);
1046  EXPECT_TRUE(text_renderer_->HasTracks());
1047  EXPECT_CALL(*this, OnEnd());
1048  SendEosNotification(1);
1049  RemoveTextTrack(1);
1050  EXPECT_FALSE(text_renderer_->HasTracks());
1051}
1052
1053TEST_F(TextRendererTest, PlayShort_SendCueThenEos) {
1054  CreateTextRenderer();
1055  AddTextTrack(kTextSubtitles, "1", "", true);
1056  AddTextTrack(kTextSubtitles, "2", "", true);
1057  Play();
1058  Pause();
1059  SendCue(0, true);
1060  EXPECT_CALL(*this, OnPause());
1061  SendEosNotification(1);
1062}
1063
1064TEST_F(TextRendererTest, PlayShort_EosThenSendCue) {
1065  CreateTextRenderer();
1066  AddTextTrack(kTextSubtitles, "1", "", true);
1067  AddTextTrack(kTextSubtitles, "2", "", true);
1068  Play();
1069  Pause();
1070  SendEosNotification(0);
1071  EXPECT_CALL(*this, OnPause());
1072  SendCue(1, true);
1073}
1074
1075TEST_F(TextRendererTest, PlayShortRemove_SendEosRemove) {
1076  CreateTextRenderer();
1077  AddTextTrack(kTextSubtitles, "1", "", true);
1078  AddTextTrack(kTextSubtitles, "2", "", true);
1079  Play();
1080  Pause();
1081  SendCue(0, true);
1082  EXPECT_CALL(*this, OnPause());
1083  SendEosNotification(1);
1084  RemoveTextTrack(0);
1085  EXPECT_TRUE(text_renderer_->HasTracks());
1086  RemoveTextTrack(1);
1087  EXPECT_FALSE(text_renderer_->HasTracks());
1088}
1089
1090TEST_F(TextRendererTest, PlayShortRemove_SendRemoveEos) {
1091  CreateTextRenderer();
1092  AddTextTrack(kTextSubtitles, "1", "", true);
1093  AddTextTrack(kTextSubtitles, "2", "", true);
1094  Play();
1095  Pause();
1096  SendCue(0, true);
1097  RemoveTextTrack(0);
1098  EXPECT_TRUE(text_renderer_->HasTracks());
1099  EXPECT_CALL(*this, OnPause());
1100  SendEosNotification(1);
1101  RemoveTextTrack(1);
1102  EXPECT_FALSE(text_renderer_->HasTracks());
1103}
1104
1105TEST_F(TextRendererTest, PlayCuePausePendingCancel_OneTrack) {
1106  CreateTextRenderer();
1107  AddTextTrack(kTextSubtitles, "", "", true);
1108  Play();
1109  Pause();
1110  EXPECT_CALL(*this, OnPause());
1111  AbortPendingRead(0);
1112}
1113
1114TEST_F(TextRendererTest, PlayCuePausePendingCancel_SendThenCancel) {
1115  CreateTextRenderer();
1116  AddTextTrack(kTextSubtitles, "1", "", true);
1117  AddTextTrack(kTextSubtitles, "2", "", true);
1118  Play();
1119  Pause();
1120  SendCue(0, true);
1121  EXPECT_CALL(*this, OnPause());
1122  AbortPendingRead(1);
1123}
1124
1125TEST_F(TextRendererTest, PlayCuePausePendingCancel_CancelThenSend) {
1126  CreateTextRenderer();
1127  AddTextTrack(kTextSubtitles, "1", "", true);
1128  AddTextTrack(kTextSubtitles, "2", "", true);
1129  Play();
1130  Pause();
1131  AbortPendingRead(0);
1132  EXPECT_CALL(*this, OnPause());
1133  SendCue(1, true);
1134}
1135
1136TEST_F(TextRendererTest, PlayCueDestroyPendingCancel_OneTrack) {
1137  CreateTextRenderer();
1138  AddTextTrack(kTextSubtitles, "", "", true);
1139  Play();
1140  Pause();
1141  EXPECT_CALL(*this, OnPause());
1142  Destroy();
1143  AbortPendingRead(0);
1144}
1145
1146TEST_F(TextRendererTest, PlayCueDestroyPendingCancel_SendThenCancel) {
1147  CreateTextRenderer();
1148  AddTextTrack(kTextSubtitles, "1", "", true);
1149  AddTextTrack(kTextSubtitles, "2", "", true);
1150  Play();
1151  Pause();
1152  EXPECT_CALL(*this, OnPause());
1153  Destroy();
1154  SendCue(0, false);
1155  AbortPendingRead(1);
1156}
1157
1158TEST_F(TextRendererTest, PlayCueDestroyPendingCancel_CancelThenSend) {
1159  CreateTextRenderer();
1160  AddTextTrack(kTextSubtitles, "1", "", true);
1161  AddTextTrack(kTextSubtitles, "2", "", true);
1162  Play();
1163  Pause();
1164  EXPECT_CALL(*this, OnPause());
1165  Destroy();
1166  AbortPendingRead(0);
1167  SendCue(1, false);
1168}
1169
1170TEST_F(TextRendererTest, AddRemoveAdd) {
1171  CreateTextRenderer();
1172  AddTextTrack(kTextSubtitles, "", "", true);
1173  Play();
1174  AbortPendingRead(0);
1175  RemoveTextTrack(0);
1176  EXPECT_CALL(*this, OnPause());
1177  Pause();
1178  AddTextTrack(kTextSubtitles, "", "", true);
1179  Play();
1180  EXPECT_CALL(*this, OnEnd());
1181  SendEosNotification(1);
1182}
1183
1184TEST_F(TextRendererTest, AddRemoveEos) {
1185  CreateTextRenderer();
1186  AddTextTrack(kTextSubtitles, "1", "", true);
1187  AddTextTrack(kTextSubtitles, "2", "", true);
1188  Play();
1189  AbortPendingRead(0);
1190  RemoveTextTrack(0);
1191  EXPECT_TRUE(text_renderer_->HasTracks());
1192  EXPECT_CALL(*this, OnEnd());
1193  SendEosNotification(1);
1194}
1195
1196TEST_F(TextRendererTest, AddRemovePause) {
1197  CreateTextRenderer();
1198  AddTextTrack(kTextSubtitles, "1", "", true);
1199  AddTextTrack(kTextSubtitles, "2", "", true);
1200  Play();
1201  AbortPendingRead(0);
1202  RemoveTextTrack(0);
1203  EXPECT_TRUE(text_renderer_->HasTracks());
1204  Pause();
1205  EXPECT_CALL(*this, OnPause());
1206  SendEosNotification(1);
1207}
1208
1209}  // namespace media
1210