blob: 15cb716713e69458bc990cb5d79274afe8b06406 [file] [log] [blame]
[email protected]912f3d6c2011-06-29 18:26:361// Copyright (c) 2011 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#include "base/synchronization/waitable_event.h"
6#include "ipc/ipc_message_utils.h"
7#include "ppapi/c/dev/ppb_fullscreen_dev.h"
8#include "ppapi/c/ppb_core.h"
9#include "ppapi/c/ppb_url_loader.h"
10#include "ppapi/c/ppp_instance.h"
11#include "ppapi/proxy/ppapi_messages.h"
12#include "ppapi/proxy/ppapi_proxy_test.h"
13
14namespace pp {
15namespace proxy {
16
17namespace {
18// This is a poor man's mock of PPP_Instance using global variables. Eventually
19// we should generalize making PPAPI interface mocks by using IDL or macro/
20// template magic.
21PP_Instance received_instance;
22uint32_t received_argc;
23std::vector<std::string> received_argn;
24std::vector<std::string> received_argv;
25PP_Bool bool_to_return;
26PP_Bool DidCreate(PP_Instance instance, uint32_t argc, const char* argn[],
27 const char* argv[]) {
28 received_instance = instance;
29 received_argc = argc;
30 received_argn.clear();
31 received_argn.insert(received_argn.begin(), argn, argn + argc);
32 received_argv.clear();
33 received_argv.insert(received_argv.begin(), argv, argv + argc);
34 return bool_to_return;
35}
36
37void DidDestroy(PP_Instance instance) {
38 received_instance = instance;
39}
40
41PP_Rect received_position;
42PP_Rect received_clip;
43// DidChangeView is asynchronous. We wait until the call has completed before
44// proceeding on to the next test.
45base::WaitableEvent did_change_view_called(false, false);
46void DidChangeView(PP_Instance instance, const PP_Rect* position,
47 const PP_Rect* clip) {
48 received_instance = instance;
49 received_position = *position;
50 received_clip = *clip;
51 did_change_view_called.Signal();
52}
53
54PP_Bool received_has_focus;
55base::WaitableEvent did_change_focus_called(false, false);
56void DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {
57 received_instance = instance;
58 received_has_focus = has_focus;
59 did_change_focus_called.Signal();
60}
61
62PP_InputEvent received_event;
63PP_Bool HandleInputEvent(PP_Instance instance, const PP_InputEvent* event) {
64 received_instance = instance;
65 memcpy(&received_event, event, sizeof(*event));;
66 return bool_to_return;
67}
68
69PP_Bool HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) {
70 // This one requires use of the PPB_URLLoader proxy and PPB_Core, plus a
71 // resource tracker for the url_loader resource.
72 // TODO(dmichael): Mock those out and test this function.
73 NOTREACHED();
74 return PP_FALSE;
75}
76
77PP_Var var_to_return;
78PP_Var GetInstanceObject(PP_Instance instance) {
79 received_instance = instance;
80 return var_to_return;
81}
82
83// Clear all the 'received' values for our mock. Call this before you expect
84// one of the functions to be invoked. TODO(dmichael): It would be better to
85// have a flag also for each function, so we know the right one got called.
86void ResetReceived() {
87 received_instance = 0;
88 received_argc = 0;
89 received_argn.clear();
90 received_argv.clear();
91 memset(&received_position, 0, sizeof(received_position));
92 memset(&received_clip, 0, sizeof(received_clip));
93 received_has_focus = PP_FALSE;
94 memset(&received_event, 0, sizeof(received_event));
95}
96
97PPP_Instance_0_4 ppp_instance_0_4 = {
98 &DidCreate,
99 &DidDestroy,
100 &DidChangeView,
101 &DidChangeFocus,
102 &HandleInputEvent,
103 &HandleDocumentLoad,
104 &GetInstanceObject
105};
106
107PPP_Instance_0_5 ppp_instance_0_5 = {
108 &DidCreate,
109 &DidDestroy,
110 &DidChangeView,
111 &DidChangeFocus,
112 &HandleInputEvent,
113 &HandleDocumentLoad
114};
115
116// PPP_Instance_Proxy::DidChangeView relies on PPB_FullscreenDev being
117// available with a valid implementation of IsFullScreen, so we mock it.
118PP_Bool IsFullscreen(PP_Instance instance) {
119 return PP_FALSE;
120}
121PPB_Fullscreen_Dev ppb_fullscreen_dev = { &IsFullscreen };
122
123} // namespace
124
125class PPP_Instance_ProxyTest : public TwoWayTest {
126 public:
127 PPP_Instance_ProxyTest()
128 : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) {
129 }
130};
131
132TEST_F(PPP_Instance_ProxyTest, PPPInstance0_4) {
133 plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_0_4, &ppp_instance_0_4);
134 host().RegisterTestInterface(PPB_FULLSCREEN_DEV_INTERFACE,
135 &ppb_fullscreen_dev);
136
137 // Try requesting the 0.5 version, like the browser does. This should come
138 // back NULL, since we're not registering 0.5. But this ensures that the
139 // behavior through the proxy code reflects more closely what happens for a
140 // real plug-in.
141 const void* interface =
142 host().host_dispatcher()->GetProxiedInterface(PPP_INSTANCE_INTERFACE_0_5);
143 EXPECT_EQ(NULL, interface);
144
145 // Grab the host-side proxy for the 0.4 interface.
146 const PPP_Instance_0_4* ppp_instance = static_cast<const PPP_Instance_0_4*>(
147 host().host_dispatcher()->GetProxiedInterface(
148 PPP_INSTANCE_INTERFACE_0_4));
149
150 // Call each function in turn, make sure we get the expected values and
151 // returns.
152 //
153 // We don't test DidDestroy, because it has the side-effect of removing the
154 // PP_Instance from the PluginDispatcher, which will cause a failure later
155 // when the test is torn down.
156 PP_Instance expected_instance = pp_instance();
157 std::vector<std::string> expected_argn, expected_argv;
158 expected_argn.push_back("Hello");
159 expected_argn.push_back("world.");
160 expected_argv.push_back("elloHay");
161 expected_argv.push_back("orldway.");
162 std::vector<const char*> argn_to_pass, argv_to_pass;
163 CHECK(expected_argn.size() == expected_argv.size());
164 for (size_t i = 0; i < expected_argn.size(); ++i) {
165 argn_to_pass.push_back(expected_argn[i].c_str());
166 argv_to_pass.push_back(expected_argv[i].c_str());
167 }
168 uint32_t expected_argc = expected_argn.size();
169 bool_to_return = PP_TRUE;
170 ResetReceived();
171 EXPECT_EQ(bool_to_return, ppp_instance->DidCreate(expected_instance,
172 expected_argc,
173 &argn_to_pass[0],
174 &argv_to_pass[0]));
175 EXPECT_EQ(received_instance, expected_instance);
176 EXPECT_EQ(received_argc, expected_argc);
177 EXPECT_EQ(received_argn, expected_argn);
178 EXPECT_EQ(received_argv, expected_argv);
179
180 PP_Rect expected_position = { {1, 2}, {3, 4} };
181 PP_Rect expected_clip = { {5, 6}, {7, 8} };
182 ResetReceived();
183 ppp_instance->DidChangeView(expected_instance, &expected_position,
184 &expected_clip);
185 did_change_view_called.Wait();
186 EXPECT_EQ(received_instance, expected_instance);
187 // If I define operator== for PP_Rect, it has to come before gtest's template
188 // definitions in the translation unit, or else it's not found. So instead of
189 // defining operator== before the #include that brings in gtest, I compare the
190 // individual parts.
191 EXPECT_EQ(received_position.point.x, expected_position.point.x);
192 EXPECT_EQ(received_position.point.y, expected_position.point.y);
193 EXPECT_EQ(received_position.size.width, expected_position.size.width);
194 EXPECT_EQ(received_position.size.height, expected_position.size.height);
195 EXPECT_EQ(received_clip.point.x, expected_clip.point.x);
196 EXPECT_EQ(received_clip.point.y, expected_clip.point.y);
197 EXPECT_EQ(received_clip.size.width, expected_clip.size.width);
198 EXPECT_EQ(received_clip.size.height, expected_clip.size.height);
199
200 PP_Bool expected_has_focus = PP_TRUE;
201 ResetReceived();
202 ppp_instance->DidChangeFocus(expected_instance, expected_has_focus);
203 did_change_focus_called.Wait();
204 EXPECT_EQ(received_instance, expected_instance);
205 EXPECT_EQ(received_has_focus, expected_has_focus);
206
207 PP_InputEvent expected_event = { PP_INPUTEVENT_TYPE_KEYDOWN, // type
208 0, // padding
209 1.0, // time_stamp
210 { { 2, 3 } } }; // u (as PP_InputEvent_Key)
211 ResetReceived();
212 EXPECT_EQ(bool_to_return,
213 ppp_instance->HandleInputEvent(expected_instance, &expected_event));
214 EXPECT_EQ(received_instance, expected_instance);
215 ASSERT_EQ(received_event.type, expected_event.type);
216 // Ignore padding; it's okay if it's not serialized.
217 EXPECT_EQ(received_event.time_stamp, expected_event.time_stamp);
218 EXPECT_EQ(received_event.u.key.modifier, expected_event.u.key.modifier);
219 EXPECT_EQ(received_event.u.key.key_code, expected_event.u.key.key_code);
220
221 // TODO(dmichael): Need to mock out a resource Tracker to be able to test
222 // HandleResourceLoad. It also requires
223 // PPB_Core.AddRefResource and for PPB_URLLoader to be
224 // registered.
225
226 var_to_return = PP_MakeInt32(100);
227 ResetReceived();
228 PP_Var result(ppp_instance->GetInstanceObject(expected_instance));
229 ASSERT_EQ(var_to_return.type, result.type);
230 EXPECT_EQ(var_to_return.value.as_int, result.value.as_int);
231 EXPECT_EQ(received_instance, expected_instance);
232}
233
234TEST_F(PPP_Instance_ProxyTest, PPPInstance0_5) {
235 plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_0_5, &ppp_instance_0_5);
236 host().RegisterTestInterface(PPB_FULLSCREEN_DEV_INTERFACE,
237 &ppb_fullscreen_dev);
238
239 // Grab the host-side proxy for the 0.5 interface.
240 const PPP_Instance_0_5* ppp_instance = static_cast<const PPP_Instance_0_5*>(
241 host().host_dispatcher()->GetProxiedInterface(
242 PPP_INSTANCE_INTERFACE_0_5));
243
244 // Call each function in turn, make sure we get the expected values and
245 // returns.
246 //
247 // We don't test DidDestroy, because it has the side-effect of removing the
248 // PP_Instance from the PluginDispatcher, which will cause a failure later
249 // when the test is torn down.
250 PP_Instance expected_instance = pp_instance();
251 std::vector<std::string> expected_argn, expected_argv;
252 expected_argn.push_back("Hello");
253 expected_argn.push_back("world.");
254 expected_argv.push_back("elloHay");
255 expected_argv.push_back("orldway.");
256 std::vector<const char*> argn_to_pass, argv_to_pass;
257 CHECK(expected_argn.size() == expected_argv.size());
258 for (size_t i = 0; i < expected_argn.size(); ++i) {
259 argn_to_pass.push_back(expected_argn[i].c_str());
260 argv_to_pass.push_back(expected_argv[i].c_str());
261 }
262 uint32_t expected_argc = expected_argn.size();
263 bool_to_return = PP_TRUE;
264 ResetReceived();
265 EXPECT_EQ(bool_to_return, ppp_instance->DidCreate(expected_instance,
266 expected_argc,
267 &argn_to_pass[0],
268 &argv_to_pass[0]));
269 EXPECT_EQ(received_instance, expected_instance);
270 EXPECT_EQ(received_argc, expected_argc);
271 EXPECT_EQ(received_argn, expected_argn);
272 EXPECT_EQ(received_argv, expected_argv);
273
274 PP_Rect expected_position = { {1, 2}, {3, 4} };
275 PP_Rect expected_clip = { {5, 6}, {7, 8} };
276 ResetReceived();
277 ppp_instance->DidChangeView(expected_instance, &expected_position,
278 &expected_clip);
279 did_change_view_called.Wait();
280 EXPECT_EQ(received_instance, expected_instance);
281 EXPECT_EQ(received_position.point.x, expected_position.point.x);
282 EXPECT_EQ(received_position.point.y, expected_position.point.y);
283 EXPECT_EQ(received_position.size.width, expected_position.size.width);
284 EXPECT_EQ(received_position.size.height, expected_position.size.height);
285 EXPECT_EQ(received_clip.point.x, expected_clip.point.x);
286 EXPECT_EQ(received_clip.point.y, expected_clip.point.y);
287 EXPECT_EQ(received_clip.size.width, expected_clip.size.width);
288 EXPECT_EQ(received_clip.size.height, expected_clip.size.height);
289
290 PP_Bool expected_has_focus = PP_TRUE;
291 ResetReceived();
292 ppp_instance->DidChangeFocus(expected_instance, expected_has_focus);
293 did_change_focus_called.Wait();
294 EXPECT_EQ(received_instance, expected_instance);
295 EXPECT_EQ(received_has_focus, expected_has_focus);
296
297 PP_InputEvent expected_event = { PP_INPUTEVENT_TYPE_KEYDOWN, // type
298 0, // padding
299 1.0, // time_stamp
300 { { 2, 3 } } }; // u (as PP_InputEvent_Key)
301 ResetReceived();
302 EXPECT_EQ(bool_to_return,
303 ppp_instance->HandleInputEvent(expected_instance, &expected_event));
304 EXPECT_EQ(received_instance, expected_instance);
305 ASSERT_EQ(received_event.type, expected_event.type);
306 // Ignore padding; it's okay if it's not serialized.
307 EXPECT_EQ(received_event.time_stamp, expected_event.time_stamp);
308 EXPECT_EQ(received_event.u.key.modifier, expected_event.u.key.modifier);
309 EXPECT_EQ(received_event.u.key.key_code, expected_event.u.key.key_code);
310
311 // TODO(dmichael): Need to mock out a resource Tracker to be able to test
312 // HandleResourceLoad. It also requires
313 // PPB_Core.AddRefResource and for PPB_URLLoader to be
314 // registered.
315}
316
317} // namespace proxy
318} // namespace pp
319