1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file.
4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind_helpers.h"
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/callback.h"
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/message_loop/message_loop.h"
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/run_loop.h"
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/strings/utf_string_conversions.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/threading/thread_checker_impl.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/child_process.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/renderer/media/media_stream_video_track.h"
14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/mock_media_stream_video_sink.h"
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/renderer/media/mock_media_stream_video_source.h"
16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/video_frame.h"
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebHeap.h"
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace content {
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const uint8 kBlackValue = 0x00;
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const uint8 kColorValue = 0xAB;
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ACTION_P(RunClosure, closure) {
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  closure.Run();
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass MediaStreamVideoTrackTest : public ::testing::Test {
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MediaStreamVideoTrackTest()
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      : child_process_(new ChildProcess()),
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        mock_source_(new MockMediaStreamVideoSource(false)),
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        source_started_(false) {
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    blink_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                              blink::WebMediaStreamSource::TypeVideo,
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                              base::UTF8ToUTF16("dummy_source_name"));
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    blink_source_.setExtraData(mock_source_);
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual ~MediaStreamVideoTrackTest() {
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void TearDown() OVERRIDE {
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink_source_.reset();
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebHeap::collectAllGarbageForTesting();
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void DeliverVideoFrameAndWaitForRenderer(MockMediaStreamVideoSink* sink) {
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::RunLoop run_loop;
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::Closure quit_closure = run_loop.QuitClosure();
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_CALL(*sink, OnVideoFrame()).WillOnce(
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        RunClosure(quit_closure));
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_refptr<media::VideoFrame> frame =
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        media::VideoFrame::CreateColorFrame(
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            gfx::Size(MediaStreamVideoSource::kDefaultWidth,
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      MediaStreamVideoSource::kDefaultHeight),
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            kColorValue, kColorValue, kColorValue, base::TimeDelta());
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    mock_source()->DeliverVideoFrame(frame);
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    run_loop.Run();
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch protected:
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::MessageLoop* io_message_loop() const {
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return child_process_->io_message_loop();
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Create a track that's associated with |mock_source_|.
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  blink::WebMediaStreamTrack CreateTrack() {
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    blink::WebMediaConstraints constraints;
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    constraints.initialize();
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool enabled = true;
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    blink::WebMediaStreamTrack track =
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        MediaStreamVideoTrack::CreateVideoTrack(
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            mock_source_, constraints,
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            MediaStreamSource::ConstraintsCallback(), enabled);
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!source_started_) {
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      mock_source_->StartMockedSource();
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      source_started_ = true;
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return track;
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockMediaStreamVideoSource* mock_source() { return mock_source_; }
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const blink::WebMediaStreamSource& blink_source() const {
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return blink_source_;
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private:
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::MessageLoopForUI message_loop_;
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<ChildProcess> child_process_;
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  blink::WebMediaStreamSource blink_source_;
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |mock_source_| is owned by |webkit_source_|.
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockMediaStreamVideoSource* mock_source_;
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool source_started_;
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
98effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(MediaStreamVideoTrackTest, AddAndRemoveSink) {
99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MockMediaStreamVideoSink sink;
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  blink::WebMediaStreamTrack track = CreateTrack();
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MediaStreamVideoSink::AddToVideoTrack(
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &sink, sink.GetDeliverFrameCB(), track);
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DeliverVideoFrameAndWaitForRenderer(&sink);
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(1, sink.number_of_frames());
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DeliverVideoFrameAndWaitForRenderer(&sink);
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_refptr<media::VideoFrame> frame =
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      media::VideoFrame::CreateBlackFrame(
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          gfx::Size(MediaStreamVideoSource::kDefaultWidth,
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    MediaStreamVideoSource::kDefaultHeight));
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  mock_source()->DeliverVideoFrame(frame);
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Wait for the IO thread to complete delivering frames.
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  io_message_loop()->RunUntilIdle();
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(2, sink.number_of_frames());
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckThreadHelper {
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckThreadHelper(base::Closure callback, bool* correct)
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : callback_(callback),
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        correct_(correct) {
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ~CheckThreadHelper() {
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *correct_ = thread_checker_.CalledOnValidThread();
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    callback_.Run();
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::Closure callback_;
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool* correct_;
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::ThreadCheckerImpl thread_checker_;
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CheckThreadVideoFrameReceiver(
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CheckThreadHelper* helper,
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const scoped_refptr<media::VideoFrame>& frame,
14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const media::VideoCaptureFormat& format,
14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::TimeTicks& estimated_capture_time) {
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Do nothing.
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Checks that the callback given to the track is reset on the right thread.
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(MediaStreamVideoTrackTest, ResetCallbackOnThread) {
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockMediaStreamVideoSink sink;
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  blink::WebMediaStreamTrack track = CreateTrack();
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::RunLoop run_loop;
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool correct = false;
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MediaStreamVideoSink::AddToVideoTrack(
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &sink,
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &CheckThreadVideoFrameReceiver,
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Owned(new CheckThreadHelper(run_loop.QuitClosure(), &correct))),
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      track);
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  run_loop.Run();
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(correct) << "Not called on correct thread.";
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
165effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(MediaStreamVideoTrackTest, SetEnabled) {
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MockMediaStreamVideoSink sink;
167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  blink::WebMediaStreamTrack track = CreateTrack();
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MediaStreamVideoSink::AddToVideoTrack(
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &sink, sink.GetDeliverFrameCB(), track);
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MediaStreamVideoTrack* video_track =
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      MediaStreamVideoTrack::GetVideoTrack(track);
173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DeliverVideoFrameAndWaitForRenderer(&sink);
175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(1, sink.number_of_frames());
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(kColorValue, *sink.last_frame()->data(media::VideoFrame::kYPlane));
177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  video_track->SetEnabled(false);
179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_FALSE(sink.enabled());
180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DeliverVideoFrameAndWaitForRenderer(&sink);
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(2, sink.number_of_frames());
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(kBlackValue, *sink.last_frame()->data(media::VideoFrame::kYPlane));
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  video_track->SetEnabled(true);
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_TRUE(sink.enabled());
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DeliverVideoFrameAndWaitForRenderer(&sink);
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(3, sink.number_of_frames());
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(kColorValue, *sink.last_frame()->data(media::VideoFrame::kYPlane));
190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
193effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(MediaStreamVideoTrackTest, SourceStopped) {
194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MockMediaStreamVideoSink sink;
195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  blink::WebMediaStreamTrack track = CreateTrack();
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MediaStreamVideoSink::AddToVideoTrack(
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &sink, sink.GetDeliverFrameCB(), track);
198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink.state());
199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  mock_source()->StopSource();
201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink.state());
202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2050529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(MediaStreamVideoTrackTest, StopLastTrack) {
2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockMediaStreamVideoSink sink1;
2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  blink::WebMediaStreamTrack track1 = CreateTrack();
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MediaStreamVideoSink::AddToVideoTrack(
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &sink1, sink1.GetDeliverFrameCB(), track1);
2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink1.state());
2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            blink_source().readyState());
2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockMediaStreamVideoSink sink2;
2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  blink::WebMediaStreamTrack track2 = CreateTrack();
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MediaStreamVideoSink::AddToVideoTrack(
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &sink2, sink2.GetDeliverFrameCB(), track2);
2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink2.state());
2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MediaStreamVideoTrack* native_track1 =
2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      MediaStreamVideoTrack::GetVideoTrack(track1);
2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  native_track1->Stop();
2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink1.state());
2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              blink_source().readyState());
2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MediaStreamVideoSink::RemoveFromVideoTrack(&sink1, track1);
2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MediaStreamVideoTrack* native_track2 =
2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        MediaStreamVideoTrack::GetVideoTrack(track2);
2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  native_track2->Stop();
2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink2.state());
2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            blink_source().readyState());
2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MediaStreamVideoSink::RemoveFromVideoTrack(&sink2, track2);
2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace content
239