1 // Copyright (c) 2012 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.
5 #include "base/synchronization/waitable_event.h"
6 #include "ipc/ipc_message_utils.h"
7 #include "ppapi/c/pp_var.h"
8 #include "ppapi/c/ppb_core.h"
9 #include "ppapi/c/ppb_fullscreen.h"
10 #include "ppapi/c/ppb_url_loader.h"
11 #include "ppapi/c/ppp_instance.h"
12 #include "ppapi/c/private/ppb_flash_fullscreen.h"
13 #include "ppapi/proxy/locking_resource_releaser.h"
14 #include "ppapi/proxy/ppapi_messages.h"
15 #include "ppapi/proxy/ppapi_proxy_test.h"
16 #include "ppapi/shared_impl/ppb_view_shared.h"
22 // This is a poor man's mock of PPP_Instance using global variables. Eventually
23 // we should generalize making PPAPI interface mocks by using IDL or macro/
25 PP_Instance received_instance
;
26 uint32_t received_argc
;
27 std::vector
<std::string
> received_argn
;
28 std::vector
<std::string
> received_argv
;
29 PP_Bool bool_to_return
;
30 PP_Bool
DidCreate(PP_Instance instance
, uint32_t argc
, const char* argn
[],
32 received_instance
= instance
;
34 received_argn
.clear();
35 received_argn
.insert(received_argn
.begin(), argn
, argn
+ argc
);
36 received_argv
.clear();
37 received_argv
.insert(received_argv
.begin(), argv
, argv
+ argc
);
38 return bool_to_return
;
41 void DidDestroy(PP_Instance instance
) {
42 received_instance
= instance
;
45 PP_Rect received_position
;
46 PP_Rect received_clip
;
47 // DidChangeView is asynchronous. We wait until the call has completed before
48 // proceeding on to the next test.
49 base::WaitableEvent
did_change_view_called(false, false);
50 void DidChangeView(PP_Instance instance
, const PP_Rect
* position
,
51 const PP_Rect
* clip
) {
52 received_instance
= instance
;
53 received_position
= *position
;
54 received_clip
= *clip
;
55 did_change_view_called
.Signal();
58 PP_Bool received_has_focus
;
59 base::WaitableEvent
did_change_focus_called(false, false);
60 void DidChangeFocus(PP_Instance instance
, PP_Bool has_focus
) {
61 received_instance
= instance
;
62 received_has_focus
= has_focus
;
63 did_change_focus_called
.Signal();
66 PP_Bool
HandleDocumentLoad(PP_Instance instance
, PP_Resource url_loader
) {
67 // This one requires use of the PPB_URLLoader proxy and PPB_Core, plus a
68 // resource tracker for the url_loader resource.
69 // TODO(dmichael): Mock those out and test this function.
74 // Clear all the 'received' values for our mock. Call this before you expect
75 // one of the functions to be invoked. TODO(dmichael): It would be better to
76 // have a flag also for each function, so we know the right one got called.
77 void ResetReceived() {
78 received_instance
= 0;
80 received_argn
.clear();
81 received_argv
.clear();
82 memset(&received_position
, 0, sizeof(received_position
));
83 memset(&received_clip
, 0, sizeof(received_clip
));
84 received_has_focus
= PP_FALSE
;
87 PPP_Instance_1_0 ppp_instance_1_0
= {
95 // PPP_Instance_Proxy::DidChangeView relies on PPB_(Flash)Fullscreen being
96 // available with a valid implementation of IsFullScreen, so we mock it.
97 PP_Bool
IsFullscreen(PP_Instance instance
) {
100 PPB_Fullscreen ppb_fullscreen
= { &IsFullscreen
};
101 PPB_FlashFullscreen ppb_flash_fullscreen
= { &IsFullscreen
};
105 class PPP_Instance_ProxyTest
: public TwoWayTest
{
107 PPP_Instance_ProxyTest()
108 : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE
) {
112 TEST_F(PPP_Instance_ProxyTest
, PPPInstance1_0
) {
113 plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_1_0
, &ppp_instance_1_0
);
114 host().RegisterTestInterface(PPB_FLASHFULLSCREEN_INTERFACE
,
115 &ppb_flash_fullscreen
);
116 host().RegisterTestInterface(PPB_FULLSCREEN_INTERFACE
,
119 // Grab the host-side proxy for the interface. The browser only speaks 1.1,
120 // while the proxy ensures support for the 1.0 version on the plugin side.
121 const PPP_Instance_1_1
* ppp_instance
= static_cast<const PPP_Instance_1_1
*>(
122 host().host_dispatcher()->GetProxiedInterface(
123 PPP_INSTANCE_INTERFACE_1_1
));
125 // Call each function in turn, make sure we get the expected values and
128 // We don't test DidDestroy, because it has the side-effect of removing the
129 // PP_Instance from the PluginDispatcher, which will cause a failure later
130 // when the test is torn down.
131 PP_Instance expected_instance
= pp_instance();
132 std::vector
<std::string
> expected_argn
, expected_argv
;
133 expected_argn
.push_back("Hello");
134 expected_argn
.push_back("world.");
135 expected_argv
.push_back("elloHay");
136 expected_argv
.push_back("orldway.");
137 std::vector
<const char*> argn_to_pass
, argv_to_pass
;
138 CHECK(expected_argn
.size() == expected_argv
.size());
139 for (size_t i
= 0; i
< expected_argn
.size(); ++i
) {
140 argn_to_pass
.push_back(expected_argn
[i
].c_str());
141 argv_to_pass
.push_back(expected_argv
[i
].c_str());
143 uint32_t expected_argc
= expected_argn
.size();
144 bool_to_return
= PP_TRUE
;
146 // Tell the host resource tracker about the instance.
147 host().resource_tracker().DidCreateInstance(expected_instance
);
148 EXPECT_EQ(bool_to_return
, ppp_instance
->DidCreate(expected_instance
,
152 EXPECT_EQ(received_instance
, expected_instance
);
153 EXPECT_EQ(received_argc
, expected_argc
);
154 EXPECT_EQ(received_argn
, expected_argn
);
155 EXPECT_EQ(received_argv
, expected_argv
);
157 PP_Rect expected_position
= { {1, 2}, {3, 4} };
158 PP_Rect expected_clip
= { {5, 6}, {7, 8} };
160 data
.rect
= expected_position
;
161 data
.is_fullscreen
= false;
162 data
.is_page_visible
= true;
163 data
.clip_rect
= expected_clip
;
164 data
.device_scale
= 1.0f
;
166 LockingResourceReleaser
view_resource(
167 (new PPB_View_Shared(OBJECT_IS_IMPL
,
168 expected_instance
, data
))->GetReference());
169 ppp_instance
->DidChangeView(expected_instance
, view_resource
.get());
170 did_change_view_called
.Wait();
171 EXPECT_EQ(received_instance
, expected_instance
);
172 EXPECT_EQ(received_position
.point
.x
, expected_position
.point
.x
);
173 EXPECT_EQ(received_position
.point
.y
, expected_position
.point
.y
);
174 EXPECT_EQ(received_position
.size
.width
, expected_position
.size
.width
);
175 EXPECT_EQ(received_position
.size
.height
, expected_position
.size
.height
);
176 EXPECT_EQ(received_clip
.point
.x
, expected_clip
.point
.x
);
177 EXPECT_EQ(received_clip
.point
.y
, expected_clip
.point
.y
);
178 EXPECT_EQ(received_clip
.size
.width
, expected_clip
.size
.width
);
179 EXPECT_EQ(received_clip
.size
.height
, expected_clip
.size
.height
);
181 PP_Bool expected_has_focus
= PP_TRUE
;
183 ppp_instance
->DidChangeFocus(expected_instance
, expected_has_focus
);
184 did_change_focus_called
.Wait();
185 EXPECT_EQ(received_instance
, expected_instance
);
186 EXPECT_EQ(received_has_focus
, expected_has_focus
);
188 // TODO(dmichael): Need to mock out a resource Tracker to be able to test
189 // HandleResourceLoad. It also requires
190 // PPB_Core.AddRefResource and for PPB_URLLoader to be
193 host().resource_tracker().DidDeleteInstance(expected_instance
);