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_VideoDestination_Private interface.
6
7#include "ppapi/tests/test_video_destination.h"
8
9#include <algorithm>
10#include <limits>
11#include <string>
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_destination_private.h"
17#include "ppapi/cpp/private/video_frame_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(VideoDestination);
23
24namespace {
25
26const PP_Resource kInvalidResource = 0;
27const PP_Instance kInvalidInstance = 0;
28
29}
30
31TestVideoDestination::TestVideoDestination(TestingInstance* instance)
32    : TestCase(instance),
33      ppb_video_destination_private_interface_(NULL),
34      ppb_core_interface_(NULL),
35      event_(instance_->pp_instance()) {
36}
37
38bool TestVideoDestination::Init() {
39  ppb_video_destination_private_interface_ =
40      static_cast<const PPB_VideoDestination_Private*>(
41          pp::Module::Get()->GetBrowserInterface(
42              PPB_VIDEODESTINATION_PRIVATE_INTERFACE));
43  if (!ppb_video_destination_private_interface_)
44    instance_->AppendError(
45        "PPB_VideoDestination_Private interface not available");
46
47  ppb_core_interface_ = static_cast<const PPB_Core*>(
48      pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
49  if (!ppb_core_interface_)
50    instance_->AppendError("PPB_Core interface not available");
51
52  return
53      ppb_video_destination_private_interface_ &&
54      ppb_core_interface_;
55}
56
57TestVideoDestination::~TestVideoDestination() {
58}
59
60void TestVideoDestination::RunTests(const std::string& filter) {
61  RUN_TEST(Create, filter);
62  RUN_TEST(PutFrame, filter);
63}
64
65void TestVideoDestination::HandleMessage(const pp::Var& message_data) {
66  if (message_data.AsString().find("blob:") == 0) {
67    stream_url_ = message_data.AsString();
68    event_.Signal();
69  }
70}
71
72std::string TestVideoDestination::TestCreate() {
73  PP_Resource video_destination;
74  // Creating a destination from an invalid instance returns an invalid
75  // resource.
76  video_destination =
77      ppb_video_destination_private_interface_->Create(kInvalidInstance);
78  ASSERT_EQ(kInvalidResource, video_destination);
79  ASSERT_FALSE(
80      ppb_video_destination_private_interface_->IsVideoDestination(
81          video_destination));
82
83  // Creating a destination from a valid instance returns a valid resource.
84  video_destination =
85      ppb_video_destination_private_interface_->Create(
86          instance_->pp_instance());
87  ASSERT_NE(kInvalidResource, video_destination);
88  ASSERT_TRUE(
89      ppb_video_destination_private_interface_->IsVideoDestination(
90          video_destination));
91
92  ppb_core_interface_->ReleaseResource(video_destination);
93  // Once released, the resource shouldn't be a video destination.
94  ASSERT_FALSE(
95      ppb_video_destination_private_interface_->IsVideoDestination(
96          video_destination));
97
98  PASS();
99}
100
101std::string TestVideoDestination::TestPutFrame() {
102  std::string js_code;
103  js_code += "var test_stream = new webkitMediaStream([]);"
104             "var url = URL.createObjectURL(test_stream);"
105             "var plugin = document.getElementById('plugin');"
106             "plugin.postMessage(url);";
107  instance_->EvalScript(js_code);
108  event_.Wait();
109
110  pp::VideoDestination_Private video_destination(instance_);
111  TestCompletionCallback cc1(instance_->pp_instance(), false);
112  cc1.WaitForResult(video_destination.Open(stream_url_, cc1.GetCallback()));
113  ASSERT_EQ(PP_OK, cc1.result());
114
115  pp::ImageData image_data(instance_,
116                           PP_IMAGEDATAFORMAT_BGRA_PREMUL,
117                           pp::Size(640, 480),
118                           false /* init_to_zero */);
119  pp::VideoFrame_Private video_frame(image_data,
120                                     0.0 /* timestamp */);
121  ASSERT_EQ(PP_OK, video_destination.PutFrame(video_frame));
122
123  video_destination.Close();
124
125  PASS();
126}
127
128