1// Copyright (c) 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// Tests PPB_VideoSource_Private interface.
6
7#include "ppapi/tests/test_video_source.h"
8
9#include <string.h>
10#include <algorithm>
11#include <limits>
12
13#include "ppapi/c/private/ppb_testing_private.h"
14#include "ppapi/cpp/completion_callback.h"
15#include "ppapi/cpp/instance.h"
16#include "ppapi/cpp/private/video_frame_private.h"
17#include "ppapi/cpp/private/video_source_private.h"
18#include "ppapi/cpp/var.h"
19#include "ppapi/tests/test_utils.h"
20#include "ppapi/tests/testing_instance.h"
21
22REGISTER_TEST_CASE(VideoSource);
23
24namespace {
25
26const PP_Resource kInvalidResource = 0;
27const PP_Instance kInvalidInstance = 0;
28
29}
30
31TestVideoSource::TestVideoSource(TestingInstance* instance)
32    : TestCase(instance),
33      ppb_video_source_private_interface_(NULL),
34      ppb_core_interface_(NULL),
35      event_(instance_->pp_instance()) {
36}
37
38bool TestVideoSource::Init() {
39  ppb_video_source_private_interface_ =
40      static_cast<const PPB_VideoSource_Private*>(
41          pp::Module::Get()->GetBrowserInterface(
42              PPB_VIDEOSOURCE_PRIVATE_INTERFACE));
43  if (!ppb_video_source_private_interface_)
44    instance_->AppendError("PPB_VideoSource_Private interface not available");
45
46  ppb_core_interface_ = static_cast<const PPB_Core*>(
47      pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
48  if (!ppb_core_interface_)
49    instance_->AppendError("PPB_Core interface not available");
50
51  return ppb_video_source_private_interface_ && ppb_core_interface_;
52}
53
54TestVideoSource::~TestVideoSource() {
55}
56
57void TestVideoSource::RunTests(const std::string& filter) {
58  RUN_TEST(Create, filter);
59  RUN_TEST(GetFrame, filter);
60}
61
62void TestVideoSource::HandleMessage(const pp::Var& message_data) {
63  if (message_data.AsString().find("blob:") == 0) {
64    stream_url_ = message_data.AsString();
65    event_.Signal();
66  }
67}
68
69std::string TestVideoSource::TestCreate() {
70  PP_Resource video_source;
71  // Creating a source from an invalid instance returns an invalid resource.
72  video_source = ppb_video_source_private_interface_->Create(kInvalidInstance);
73  ASSERT_EQ(kInvalidResource, video_source);
74  ASSERT_FALSE(
75      ppb_video_source_private_interface_->IsVideoSource(video_source));
76
77  // Creating a source from a valid instance returns a valid resource.
78  video_source =
79      ppb_video_source_private_interface_->Create(instance_->pp_instance());
80  ASSERT_NE(kInvalidResource, video_source);
81  ASSERT_TRUE(
82      ppb_video_source_private_interface_->IsVideoSource(video_source));
83
84  ppb_core_interface_->ReleaseResource(video_source);
85  // Once released, the resource shouldn't be a video source.
86  ASSERT_FALSE(
87      ppb_video_source_private_interface_->IsVideoSource(video_source));
88
89  PASS();
90}
91
92std::string TestVideoSource::TestGetFrame() {
93  std::string js_code;
94  js_code += "var test_stream;"
95             "function gotStream(stream){"
96             "  test_stream = stream;"
97             "  var url = URL.createObjectURL(test_stream);"
98             "  var plugin = document.getElementById('plugin');"
99             "  plugin.postMessage(url);"
100             "}"
101             "navigator.webkitGetUserMedia("
102             "{audio:false, video:true}, gotStream, function() {});";
103  instance_->EvalScript(js_code);
104  event_.Wait();
105
106  pp::VideoSource_Private video_source(instance_);
107  TestCompletionCallback cc1(instance_->pp_instance(), false);
108  cc1.WaitForResult(video_source.Open(stream_url_, cc1.GetCallback()));
109  ASSERT_EQ(PP_OK, cc1.result());
110  TestCompletionCallbackWithOutput<pp::VideoFrame_Private> cc2(
111      instance_->pp_instance(), false);
112  cc2.WaitForResult(video_source.GetFrame(cc2.GetCallback()));
113  ASSERT_EQ(PP_OK, cc2.result());
114  const pp::VideoFrame_Private video_frame = cc2.output();
115  ASSERT_FALSE(video_frame.image_data().is_null());
116
117  video_source.Close();
118
119  PASS();
120}
121
122