1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// found in the LICENSE file.
4a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/message_loop/message_loop.h"
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/run_loop.h"
7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/strings/utf_string_conversions.h"
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/child_process.h"
9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/renderer/media/media_stream_video_track.h"
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/renderer/media/mock_media_stream_video_sink.h"
11a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "media/base/video_frame.h"
14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebHeap.h"
16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.h"
17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace content {
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ACTION_P(RunClosure, closure) {
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  closure.Run();
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass MediaStreamRemoteVideoSourceUnderTest
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : public MediaStreamRemoteVideoSource {
26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public:
27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  MediaStreamRemoteVideoSourceUnderTest(webrtc::VideoTrackInterface* track)
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : MediaStreamRemoteVideoSource(track) {
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) using MediaStreamRemoteVideoSource::RenderInterfaceForTest;
31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass MediaStreamRemoteVideoSourceTest
34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : public ::testing::Test {
35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public:
36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  MediaStreamRemoteVideoSourceTest()
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      : child_process_(new ChildProcess()),
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        mock_factory_(new MockPeerConnectionDependencyFactory()),
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        webrtc_video_track_(mock_factory_->CreateLocalVideoTrack(
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            "test",
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            static_cast<cricket::VideoCapturer*>(NULL))),
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        remote_source_(new MediaStreamRemoteVideoSourceUnderTest(
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            webrtc_video_track_.get())),
44a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        number_of_successful_constraints_applied_(0),
45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        number_of_failed_constraints_applied_(0) {
46a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    webkit_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
47a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              blink::WebMediaStreamSource::TypeVideo,
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              base::UTF8ToUTF16("dummy_source_name"));
49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    webkit_source_.setExtraData(remote_source_);
50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
51a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void TearDown() OVERRIDE {
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    webkit_source_.reset();
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebHeap::collectAllGarbageForTesting();
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  MediaStreamRemoteVideoSourceUnderTest* source() {
58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return remote_source_;
59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
60a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MediaStreamVideoTrack* CreateTrack() {
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool enabled = true;
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebMediaConstraints constraints;
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    constraints.initialize();
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return new MediaStreamVideoTrack(
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        source(),
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        constraints,
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            &MediaStreamRemoteVideoSourceTest::OnConstraintsApplied,
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            base::Unretained(this)),
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        enabled);
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int NumberOfSuccessConstraintsCallbacks() const {
75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return number_of_successful_constraints_applied_;
76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int NumberOfFailedConstraintsCallbacks() const {
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return number_of_failed_constraints_applied_;
80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  void StopWebRtcTrack() {
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    static_cast<MockWebRtcVideoTrack*>(webrtc_video_track_.get())->set_state(
84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        webrtc::MediaStreamTrackInterface::kEnded);
85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const blink::WebMediaStreamSource& webkit_source() const {
88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return  webkit_source_;
89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private:
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void OnConstraintsApplied(MediaStreamSource* source,
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                            MediaStreamRequestResult result,
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                            const blink::WebString& result_name) {
95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    ASSERT_EQ(source, remote_source_);
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (result == MEDIA_DEVICE_OK)
97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ++number_of_successful_constraints_applied_;
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    else
99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ++number_of_failed_constraints_applied_;
100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::MessageLoopForUI message_loop_;
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<ChildProcess> child_process_;
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<MockPeerConnectionDependencyFactory> mock_factory_;
105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_refptr<webrtc::VideoTrackInterface> webrtc_video_track_;
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // |remote_source_| is owned by |webkit_source_|.
107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  MediaStreamRemoteVideoSourceUnderTest* remote_source_;
108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  blink::WebMediaStreamSource webkit_source_;
109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int number_of_successful_constraints_applied_;
110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int number_of_failed_constraints_applied_;
111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
113a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<MediaStreamVideoTrack> track(CreateTrack());
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MockMediaStreamVideoSink sink;
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  track->AddSink(&sink, sink.GetDeliverFrameCB());
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::RunLoop run_loop;
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::Closure quit_closure = run_loop.QuitClosure();
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_CALL(sink, OnVideoFrame()).WillOnce(
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      RunClosure(quit_closure));
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  cricket::WebRtcVideoFrame webrtc_frame;
124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  webrtc_frame.InitToBlack(320, 240, 1, 1, 0, 1);
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  source()->RenderInterfaceForTest()->RenderFrame(&webrtc_frame);
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  run_loop.Run();
127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_EQ(1, sink.number_of_frames());
129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  track->RemoveSink(&sink);
130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
132a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTEST_F(MediaStreamRemoteVideoSourceTest, RemoteTrackStop) {
133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<MediaStreamVideoTrack> track(CreateTrack());
134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MockMediaStreamVideoSink sink;
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  track->AddSink(&sink, sink.GetDeliverFrameCB());
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink.state());
138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            webkit_source().readyState());
140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  StopWebRtcTrack();
141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            webkit_source().readyState());
143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink.state());
144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  track->RemoveSink(&sink);
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}  // namespace content
149