- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / pepper / pepper_gamepad_host_unittest.cc
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.
4
5 #include <string.h>
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/memory/weak_ptr.h"
9 #include "content/browser/gamepad/gamepad_test_helpers.h"
10 #include "content/browser/renderer_host/pepper/browser_ppapi_host_test.h"
11 #include "content/browser/renderer_host/pepper/pepper_gamepad_host.h"
12 #include "content/common/gamepad_hardware_buffer.h"
13 #include "ppapi/c/pp_errors.h"
14 #include "ppapi/host/host_message_context.h"
15 #include "ppapi/proxy/gamepad_resource.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/proxy/resource_message_params.h"
18 #include "ppapi/shared_impl/ppb_gamepad_shared.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace content {
22
23 namespace {
24
25 class PepperGamepadHostTest
26     : public testing::Test,
27       public BrowserPpapiHostTest {
28  public:
29   PepperGamepadHostTest() {
30   }
31   virtual ~PepperGamepadHostTest() {
32   }
33
34   void ConstructService(const WebKit::WebGamepads& test_data) {
35     service_.reset(new GamepadServiceTestConstructor(test_data));
36   }
37
38   GamepadService* gamepad_service() { return service_->gamepad_service(); }
39
40  protected:
41   scoped_ptr<GamepadServiceTestConstructor> service_;
42
43   DISALLOW_COPY_AND_ASSIGN(PepperGamepadHostTest);
44 };
45
46 inline ptrdiff_t AddressDiff(const void* a, const void* b) {
47   return static_cast<const char*>(a) - static_cast<const char*>(b);
48 }
49
50 }  // namespace
51
52 // Validate the memory layout of the Pepper proxy struct matches the content
53 // one. The proxy can't depend on content so has a duplicate definition. This
54 // code can see both definitions so we do the validation here.
55 TEST_F(PepperGamepadHostTest, ValidateHardwareBuffersMatch) {
56   // Hardware buffer.
57   COMPILE_ASSERT(sizeof(ppapi::ContentGamepadHardwareBuffer) ==
58                  sizeof(GamepadHardwareBuffer),
59                  gamepad_hardware_buffers_must_match);
60   ppapi::ContentGamepadHardwareBuffer ppapi_buf;
61   GamepadHardwareBuffer content_buf;
62   EXPECT_EQ(AddressDiff(&content_buf.sequence, &content_buf),
63             AddressDiff(&ppapi_buf.sequence, &ppapi_buf));
64   EXPECT_EQ(AddressDiff(&content_buf.buffer, &content_buf),
65             AddressDiff(&ppapi_buf.buffer, &ppapi_buf));
66 }
67
68 TEST_F(PepperGamepadHostTest, ValidateGamepadsMatch) {
69   // Gamepads.
70   COMPILE_ASSERT(sizeof(ppapi::WebKitGamepads) ==
71                  sizeof(WebKit::WebGamepads),
72                  gamepads_data_must_match);
73   ppapi::WebKitGamepads ppapi_gamepads;
74   WebKit::WebGamepads web_gamepads;
75   EXPECT_EQ(AddressDiff(&web_gamepads.length, &web_gamepads),
76             AddressDiff(&ppapi_gamepads.length, &ppapi_gamepads));
77
78   // See comment below on storage & the EXPECT macro.
79   size_t webkit_items_length_cap = WebKit::WebGamepads::itemsLengthCap;
80   size_t ppapi_items_length_cap = ppapi::WebKitGamepads::kItemsLengthCap;
81   EXPECT_EQ(webkit_items_length_cap, ppapi_items_length_cap);
82
83   for (size_t i = 0; i < web_gamepads.itemsLengthCap; i++) {
84     EXPECT_EQ(AddressDiff(&web_gamepads.items[0], &web_gamepads),
85               AddressDiff(&ppapi_gamepads.items[0], &ppapi_gamepads));
86   }
87 }
88
89 TEST_F(PepperGamepadHostTest, ValidateGamepadMatch) {
90   // Gamepad.
91   COMPILE_ASSERT(sizeof(ppapi::WebKitGamepad) ==
92                  sizeof(WebKit::WebGamepad),
93                  gamepad_data_must_match);
94   ppapi::WebKitGamepad ppapi_gamepad;
95   WebKit::WebGamepad web_gamepad;
96
97   // Using EXPECT seems to force storage for the parameter, which the constants
98   // in the WebKit/PPAPI headers don't have. So we have to use temporaries
99   // before comparing them.
100   size_t webkit_id_length_cap = WebKit::WebGamepad::idLengthCap;
101   size_t ppapi_id_length_cap = ppapi::WebKitGamepad::kIdLengthCap;
102   EXPECT_EQ(webkit_id_length_cap, ppapi_id_length_cap);
103
104   size_t webkit_axes_length_cap = WebKit::WebGamepad::axesLengthCap;
105   size_t ppapi_axes_length_cap = ppapi::WebKitGamepad::kAxesLengthCap;
106   EXPECT_EQ(webkit_axes_length_cap, ppapi_axes_length_cap);
107
108   size_t webkit_buttons_length_cap = WebKit::WebGamepad::buttonsLengthCap;
109   size_t ppapi_buttons_length_cap = ppapi::WebKitGamepad::kButtonsLengthCap;
110   EXPECT_EQ(webkit_buttons_length_cap, ppapi_buttons_length_cap);
111
112   EXPECT_EQ(AddressDiff(&web_gamepad.connected, &web_gamepad),
113             AddressDiff(&ppapi_gamepad.connected, &ppapi_gamepad));
114   EXPECT_EQ(AddressDiff(&web_gamepad.id, &web_gamepad),
115             AddressDiff(&ppapi_gamepad.id, &ppapi_gamepad));
116   EXPECT_EQ(AddressDiff(&web_gamepad.timestamp, &web_gamepad),
117             AddressDiff(&ppapi_gamepad.timestamp, &ppapi_gamepad));
118   EXPECT_EQ(AddressDiff(&web_gamepad.axesLength, &web_gamepad),
119             AddressDiff(&ppapi_gamepad.axes_length, &ppapi_gamepad));
120   EXPECT_EQ(AddressDiff(&web_gamepad.axes, &web_gamepad),
121             AddressDiff(&ppapi_gamepad.axes, &ppapi_gamepad));
122   EXPECT_EQ(AddressDiff(&web_gamepad.buttonsLength, &web_gamepad),
123             AddressDiff(&ppapi_gamepad.buttons_length, &ppapi_gamepad));
124   EXPECT_EQ(AddressDiff(&web_gamepad.buttons, &web_gamepad),
125             AddressDiff(&ppapi_gamepad.buttons, &ppapi_gamepad));
126 }
127
128 TEST_F(PepperGamepadHostTest, WaitForReply) {
129   WebKit::WebGamepads default_data;
130   memset(&default_data, 0, sizeof(WebKit::WebGamepads));
131   default_data.length = 1;
132   default_data.items[0].connected = true;
133   default_data.items[0].buttonsLength = 1;
134   ConstructService(default_data);
135
136   PP_Instance pp_instance = 12345;
137   PP_Resource pp_resource = 67890;
138   PepperGamepadHost gamepad_host(gamepad_service(), GetBrowserPpapiHost(),
139                                  pp_instance, pp_resource);
140
141   // Synthesize a request for gamepad data.
142   ppapi::host::HostMessageContext context(
143       ppapi::proxy::ResourceMessageCallParams(pp_resource, 1));
144   EXPECT_EQ(PP_OK_COMPLETIONPENDING,
145             gamepad_host.OnResourceMessageReceived(
146                 PpapiHostMsg_Gamepad_RequestMemory(),
147                 &context));
148
149   // Wait for the gamepad background thread to read twice to make sure we
150   // don't get a message yet (see below for why).
151   MockGamepadDataFetcher* fetcher = service_->data_fetcher();
152   fetcher->WaitForDataRead();
153   fetcher->WaitForDataRead();
154
155   // It should not have sent the callback message.
156   service_->message_loop().RunUntilIdle();
157   EXPECT_EQ(0u, sink().message_count());
158
159   // Set a button down and wait for it to be read twice.
160   //
161   // We wait for two reads before calling RunAllPending because the provider
162   // will read the data on the background thread (setting the event) and *then*
163   // will issue the callback on our thread. Waiting for it to read twice
164   // ensures that it was able to issue callbacks for the first read (if it
165   // issued one) before we try to check for it.
166   WebKit::WebGamepads button_down_data = default_data;
167   button_down_data.items[0].buttons[0] = 1.f;
168   fetcher->SetTestData(button_down_data);
169   fetcher->WaitForDataRead();
170   fetcher->WaitForDataRead();
171
172   // It should have sent a callback.
173   service_->message_loop().RunUntilIdle();
174   ppapi::proxy::ResourceMessageReplyParams reply_params;
175   IPC::Message reply_msg;
176   ASSERT_TRUE(sink().GetFirstResourceReplyMatching(
177       PpapiPluginMsg_Gamepad_SendMemory::ID, &reply_params, &reply_msg));
178
179   // Extract the shared memory handle.
180   base::SharedMemoryHandle reply_handle;
181   EXPECT_TRUE(reply_params.TakeSharedMemoryHandleAtIndex(0, &reply_handle));
182
183   // Validate the shared memory.
184   base::SharedMemory shared_memory(reply_handle, true);
185   EXPECT_TRUE(shared_memory.Map(sizeof(ppapi::ContentGamepadHardwareBuffer)));
186   const ppapi::ContentGamepadHardwareBuffer* buffer =
187       static_cast<const ppapi::ContentGamepadHardwareBuffer*>(
188           shared_memory.memory());
189   EXPECT_EQ(button_down_data.length, buffer->buffer.length);
190   EXPECT_EQ(button_down_data.items[0].buttonsLength,
191             buffer->buffer.items[0].buttons_length);
192   for (size_t i = 0; i < ppapi::WebKitGamepad::kButtonsLengthCap; i++) {
193     EXPECT_EQ(button_down_data.items[0].buttons[i],
194               buffer->buffer.items[0].buttons[i]);
195   }
196
197   // Duplicate requests should be denied.
198   EXPECT_EQ(PP_ERROR_FAILED,
199             gamepad_host.OnResourceMessageReceived(
200                 PpapiHostMsg_Gamepad_RequestMemory(),
201                 &context));
202 }
203
204 }  // namespace content