Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / media_stream_video_track_unittest.cc
index 242b9ce..949b017 100644 (file)
@@ -2,57 +2,59 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/threading/thread_checker_impl.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream_video_track.h"
-#include "content/renderer/media/mock_media_stream_dependency_factory.h"
+#include "content/renderer/media/mock_media_stream_video_sink.h"
 #include "content/renderer/media/mock_media_stream_video_source.h"
 #include "media/base/video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 
-class MockVideoSink : public MediaStreamVideoSink {
- public:
-  MockVideoSink()
-      : number_of_frames_(0), enabled_(true),
-        state_(blink::WebMediaStreamSource::ReadyStateLive) {
-  }
-
-  virtual void OnVideoFrame(
-      const scoped_refptr<media::VideoFrame>& frame) OVERRIDE {
-    ++number_of_frames_;
-  }
-
-  virtual void OnReadyStateChanged(
-        blink::WebMediaStreamSource::ReadyState state) OVERRIDE {
-    state_ = state;
-  }
-
-  virtual void OnEnabledChanged(bool enabled) OVERRIDE {
-    enabled_ = enabled;
-  }
-
-  int number_of_frames() const { return number_of_frames_; }
-  bool enabled() const { return enabled_; }
-  blink::WebMediaStreamSource::ReadyState state() const { return state_; }
-
- private:
-  int number_of_frames_;
-  bool enabled_;
-  blink::WebMediaStreamSource::ReadyState state_;
-};
+ACTION_P(RunClosure, closure) {
+  closure.Run();
+}
 
 class MediaStreamVideoTrackTest : public ::testing::Test {
  public:
   MediaStreamVideoTrackTest()
-      : mock_source_(new MockMediaStreamVideoSource(&factory_, false)) {
-    webkit_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
+      : child_process_(new ChildProcess()),
+        mock_source_(new MockMediaStreamVideoSource(false)),
+        source_started_(false) {
+    blink_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
                               blink::WebMediaStreamSource::TypeVideo,
                               base::UTF8ToUTF16("dummy_source_name"));
-    webkit_source_.setExtraData(mock_source_);
+    blink_source_.setExtraData(mock_source_);
+  }
+
+  virtual ~MediaStreamVideoTrackTest() {
+  }
+
+  void DeliverVideoFrameAndWaitForRenderer(MockMediaStreamVideoSink* sink) {
+    base::RunLoop run_loop;
+    base::Closure quit_closure = run_loop.QuitClosure();
+    EXPECT_CALL(*sink, OnVideoFrame()).WillOnce(
+        RunClosure(quit_closure));
+    scoped_refptr<media::VideoFrame> frame =
+        media::VideoFrame::CreateBlackFrame(
+            gfx::Size(MediaStreamVideoSource::kDefaultWidth,
+                      MediaStreamVideoSource::kDefaultHeight));
+    mock_source()->DeliverVideoFrame(frame);
+    run_loop.Run();
   }
 
  protected:
+  base::MessageLoop* io_message_loop() const {
+    return child_process_->io_message_loop();
+  }
+
   // Create a track that's associated with |mock_source_|.
   blink::WebMediaStreamTrack CreateTrack() {
     blink::WebMediaConstraints constraints;
@@ -61,79 +63,131 @@ class MediaStreamVideoTrackTest : public ::testing::Test {
     blink::WebMediaStreamTrack track =
         MediaStreamVideoTrack::CreateVideoTrack(
             mock_source_, constraints,
-            MediaStreamSource::ConstraintsCallback(), enabled, &factory_);
-    mock_source_->StartMockedSource();
-
+            MediaStreamSource::ConstraintsCallback(), enabled);
+    if (!source_started_) {
+      mock_source_->StartMockedSource();
+      source_started_ = true;
+    }
     return track;
   }
 
   MockMediaStreamVideoSource* mock_source() { return mock_source_; }
+  const blink::WebMediaStreamSource& blink_source() const {
+    return blink_source_;
+  }
 
  private:
-  MockMediaStreamDependencyFactory factory_;
-  blink::WebMediaStreamSource webkit_source_;
+  base::MessageLoopForUI message_loop_;
+  scoped_ptr<ChildProcess> child_process_;
+  blink::WebMediaStreamSource blink_source_;
   // |mock_source_| is owned by |webkit_source_|.
   MockMediaStreamVideoSource* mock_source_;
+  bool source_started_;
 };
 
-TEST_F(MediaStreamVideoTrackTest, GetAdapter) {
-  blink::WebMediaStreamTrack track = CreateTrack();
-  MediaStreamVideoTrack* video_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
-  EXPECT_TRUE(video_track->GetVideoAdapter() != NULL);
-}
-
 TEST_F(MediaStreamVideoTrackTest, AddAndRemoveSink) {
-  MockVideoSink sink;
+  MockMediaStreamVideoSink sink;
   blink::WebMediaStreamTrack track = CreateTrack();
-  MediaStreamVideoSink::AddToVideoTrack(&sink, track);
+  MediaStreamVideoSink::AddToVideoTrack(
+      &sink, sink.GetDeliverFrameCB(), track);
+
+  DeliverVideoFrameAndWaitForRenderer(&sink);
+  EXPECT_EQ(1, sink.number_of_frames());
+
+  DeliverVideoFrameAndWaitForRenderer(&sink);
+
+  MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
 
-  MediaStreamVideoTrack* video_track =
-        MediaStreamVideoTrack::GetVideoTrack(track);
   scoped_refptr<media::VideoFrame> frame =
       media::VideoFrame::CreateBlackFrame(
           gfx::Size(MediaStreamVideoSource::kDefaultWidth,
                     MediaStreamVideoSource::kDefaultHeight));
-  video_track->OnVideoFrame(frame);
-  EXPECT_EQ(1, sink.number_of_frames());
-  video_track->OnVideoFrame(frame);
+  mock_source()->DeliverVideoFrame(frame);
+  // Wait for the IO thread to complete delivering frames.
+  io_message_loop()->RunUntilIdle();
   EXPECT_EQ(2, sink.number_of_frames());
+}
 
+class CheckThreadHelper {
+ public:
+  CheckThreadHelper(base::Closure callback, bool* correct)
+      : callback_(callback),
+        correct_(correct) {
+  }
+
+  ~CheckThreadHelper() {
+    *correct_ = thread_checker_.CalledOnValidThread();
+    callback_.Run();
+  }
+
+ private:
+  base::Closure callback_;
+  bool* correct_;
+  base::ThreadCheckerImpl thread_checker_;
+};
+
+void CheckThreadVideoFrameReceiver(
+    CheckThreadHelper* helper,
+    const scoped_refptr<media::VideoFrame>& frame,
+    const media::VideoCaptureFormat& format) {
+  // Do nothing.
+}
+
+// Checks that the callback given to the track is reset on the right thread.
+TEST_F(MediaStreamVideoTrackTest, ResetCallbackOnThread) {
+  MockMediaStreamVideoSink sink;
+  blink::WebMediaStreamTrack track = CreateTrack();
+
+  base::RunLoop run_loop;
+  bool correct = false;
+  MediaStreamVideoSink::AddToVideoTrack(
+      &sink,
+      base::Bind(
+          &CheckThreadVideoFrameReceiver,
+          base::Owned(new CheckThreadHelper(run_loop.QuitClosure(), &correct))),
+      track);
   MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
-  video_track->OnVideoFrame(frame);
-  EXPECT_EQ(2, sink.number_of_frames());
+  run_loop.Run();
+  EXPECT_TRUE(correct) << "Not called on correct thread.";
 }
 
 TEST_F(MediaStreamVideoTrackTest, SetEnabled) {
-  MockVideoSink sink;
+  MockMediaStreamVideoSink sink;
   blink::WebMediaStreamTrack track = CreateTrack();
-  MediaStreamVideoSink::AddToVideoTrack(&sink, track);
+  MediaStreamVideoSink::AddToVideoTrack(
+      &sink, sink.GetDeliverFrameCB(), track);
 
   MediaStreamVideoTrack* video_track =
       MediaStreamVideoTrack::GetVideoTrack(track);
-  scoped_refptr<media::VideoFrame> frame =
-      media::VideoFrame::CreateBlackFrame(
-          gfx::Size(MediaStreamVideoSource::kDefaultWidth,
-                    MediaStreamVideoSource::kDefaultHeight));
-  video_track->OnVideoFrame(frame);
+
+  DeliverVideoFrameAndWaitForRenderer(&sink);
   EXPECT_EQ(1, sink.number_of_frames());
 
   video_track->SetEnabled(false);
   EXPECT_FALSE(sink.enabled());
-  video_track->OnVideoFrame(frame);
+
+  scoped_refptr<media::VideoFrame> frame =
+      media::VideoFrame::CreateBlackFrame(
+          gfx::Size(MediaStreamVideoSource::kDefaultWidth,
+                    MediaStreamVideoSource::kDefaultHeight));
+  mock_source()->DeliverVideoFrame(frame);
+  // Wait for the IO thread to complete delivering frames.
+  io_message_loop()->RunUntilIdle();
   EXPECT_EQ(1, sink.number_of_frames());
 
   video_track->SetEnabled(true);
   EXPECT_TRUE(sink.enabled());
-  video_track->OnVideoFrame(frame);
+  mock_source()->DeliverVideoFrame(frame);
+  DeliverVideoFrameAndWaitForRenderer(&sink);
   EXPECT_EQ(2, sink.number_of_frames());
   MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
 }
 
 TEST_F(MediaStreamVideoTrackTest, SourceStopped) {
-  MockVideoSink sink;
+  MockMediaStreamVideoSink sink;
   blink::WebMediaStreamTrack track = CreateTrack();
-  MediaStreamVideoSink::AddToVideoTrack(&sink, track);
+  MediaStreamVideoSink::AddToVideoTrack(
+      &sink, sink.GetDeliverFrameCB(), track);
   EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink.state());
 
   mock_source()->StopSource();
@@ -141,4 +195,37 @@ TEST_F(MediaStreamVideoTrackTest, SourceStopped) {
   MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
 }
 
+TEST_F(MediaStreamVideoTrackTest, StopLastTrack) {
+  MockMediaStreamVideoSink sink1;
+  blink::WebMediaStreamTrack track1 = CreateTrack();
+  MediaStreamVideoSink::AddToVideoTrack(
+      &sink1, sink1.GetDeliverFrameCB(), track1);
+  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink1.state());
+
+  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
+            blink_source().readyState());
+
+  MockMediaStreamVideoSink sink2;
+  blink::WebMediaStreamTrack track2 = CreateTrack();
+  MediaStreamVideoSink::AddToVideoTrack(
+      &sink2, sink2.GetDeliverFrameCB(), track2);
+  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink2.state());
+
+  MediaStreamVideoTrack* native_track1 =
+      MediaStreamVideoTrack::GetVideoTrack(track1);
+  native_track1->Stop();
+  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink1.state());
+  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
+              blink_source().readyState());
+  MediaStreamVideoSink::RemoveFromVideoTrack(&sink1, track1);
+
+  MediaStreamVideoTrack* native_track2 =
+        MediaStreamVideoTrack::GetVideoTrack(track2);
+  native_track2->Stop();
+  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink2.state());
+  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
+            blink_source().readyState());
+  MediaStreamVideoSink::RemoveFromVideoTrack(&sink2, track2);
+}
+
 }  // namespace content