| Index: content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
|
| diff --git a/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc b/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c5a09f7eb094e234ce895d9227c31dc61633b86d
|
| --- /dev/null
|
| +++ b/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
|
| @@ -0,0 +1,204 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <string.h>
|
| +
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "content/browser/gamepad/gamepad_test_helpers.h"
|
| +#include "content/browser/renderer_host/pepper/browser_ppapi_host_test.h"
|
| +#include "content/browser/renderer_host/pepper/pepper_gamepad_host.h"
|
| +#include "content/common/gamepad_hardware_buffer.h"
|
| +#include "ppapi/c/pp_errors.h"
|
| +#include "ppapi/host/host_message_context.h"
|
| +#include "ppapi/proxy/gamepad_resource.h"
|
| +#include "ppapi/proxy/ppapi_messages.h"
|
| +#include "ppapi/proxy/resource_message_params.h"
|
| +#include "ppapi/shared_impl/ppb_gamepad_shared.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace content {
|
| +
|
| +namespace {
|
| +
|
| +class PepperGamepadHostTest
|
| + : public testing::Test,
|
| + public BrowserPpapiHostTest {
|
| + public:
|
| + PepperGamepadHostTest() {
|
| + }
|
| + ~PepperGamepadHostTest() {
|
| + }
|
| +
|
| + void ConstructService(const WebKit::WebGamepads& test_data) {
|
| + service_.reset(new GamepadServiceTestConstructor(test_data));
|
| + }
|
| +
|
| + GamepadService* gamepad_service() { return service_->gamepad_service(); }
|
| +
|
| + protected:
|
| + scoped_ptr<GamepadServiceTestConstructor> service_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PepperGamepadHostTest);
|
| +};
|
| +
|
| +inline ptrdiff_t AddressDiff(const void* a, const void* b) {
|
| + return static_cast<const char*>(a) - static_cast<const char*>(b);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Validate the memory layout of the Pepper proxy struct matches the content
|
| +// one. The proxy can't depend on content so has a duplicate definition. This
|
| +// code can see both definitions so we do the validation here.
|
| +TEST_F(PepperGamepadHostTest, ValidateHardwareBuffersMatch) {
|
| + // Hardware buffer.
|
| + COMPILE_ASSERT(sizeof(ppapi::ContentGamepadHardwareBuffer) ==
|
| + sizeof(content::GamepadHardwareBuffer),
|
| + gamepad_hardware_buffers_must_match);
|
| + ppapi::ContentGamepadHardwareBuffer ppapi_buf;
|
| + GamepadHardwareBuffer content_buf;
|
| + EXPECT_EQ(AddressDiff(&content_buf.sequence, &content_buf),
|
| + AddressDiff(&ppapi_buf.sequence, &ppapi_buf));
|
| + EXPECT_EQ(AddressDiff(&content_buf.buffer, &content_buf),
|
| + AddressDiff(&ppapi_buf.buffer, &ppapi_buf));
|
| +}
|
| +
|
| +TEST_F(PepperGamepadHostTest, ValidateGamepadsMatch) {
|
| + // Gamepads.
|
| + COMPILE_ASSERT(sizeof(ppapi::WebKitGamepads) ==
|
| + sizeof(WebKit::WebGamepads),
|
| + gamepads_data_must_match);
|
| + ppapi::WebKitGamepads ppapi_gamepads;
|
| + WebKit::WebGamepads web_gamepads;
|
| + EXPECT_EQ(AddressDiff(&web_gamepads.length, &web_gamepads),
|
| + AddressDiff(&ppapi_gamepads.length, &ppapi_gamepads));
|
| +
|
| + // See comment below on storage & the EXPECT macro.
|
| + size_t webkit_items_length_cap = WebKit::WebGamepads::itemsLengthCap;
|
| + size_t ppapi_items_length_cap = ppapi::WebKitGamepads::kItemsLengthCap;
|
| + EXPECT_EQ(webkit_items_length_cap, ppapi_items_length_cap);
|
| +
|
| + for (size_t i = 0; i < web_gamepads.itemsLengthCap; i++) {
|
| + EXPECT_EQ(AddressDiff(&web_gamepads.items[0], &web_gamepads),
|
| + AddressDiff(&ppapi_gamepads.items[0], &ppapi_gamepads));
|
| + }
|
| +}
|
| +
|
| +TEST_F(PepperGamepadHostTest, ValidateGamepadMatch) {
|
| + // Gamepad.
|
| + COMPILE_ASSERT(sizeof(ppapi::WebKitGamepad) ==
|
| + sizeof(WebKit::WebGamepad),
|
| + gamepad_data_must_match);
|
| + ppapi::WebKitGamepad ppapi_gamepad;
|
| + WebKit::WebGamepad web_gamepad;
|
| +
|
| + // Using EXPECT seems to force storage for the parameter, which the constants
|
| + // in the WebKit/PPAPI headers don't have. So we have to use temporaries
|
| + // before comparing them.
|
| + size_t webkit_id_length_cap = WebKit::WebGamepad::idLengthCap;
|
| + size_t ppapi_id_length_cap = ppapi::WebKitGamepad::kIdLengthCap;
|
| + EXPECT_EQ(webkit_id_length_cap, ppapi_id_length_cap);
|
| +
|
| + size_t webkit_axes_length_cap = WebKit::WebGamepad::axesLengthCap;
|
| + size_t ppapi_axes_length_cap = ppapi::WebKitGamepad::kAxesLengthCap;
|
| + EXPECT_EQ(webkit_axes_length_cap, ppapi_axes_length_cap);
|
| +
|
| + size_t webkit_buttons_length_cap = WebKit::WebGamepad::buttonsLengthCap;
|
| + size_t ppapi_buttons_length_cap = ppapi::WebKitGamepad::kButtonsLengthCap;
|
| + EXPECT_EQ(webkit_buttons_length_cap, ppapi_buttons_length_cap);
|
| +
|
| + EXPECT_EQ(AddressDiff(&web_gamepad.connected, &web_gamepad),
|
| + AddressDiff(&ppapi_gamepad.connected, &ppapi_gamepad));
|
| + EXPECT_EQ(AddressDiff(&web_gamepad.id, &web_gamepad),
|
| + AddressDiff(&ppapi_gamepad.id, &ppapi_gamepad));
|
| + EXPECT_EQ(AddressDiff(&web_gamepad.timestamp, &web_gamepad),
|
| + AddressDiff(&ppapi_gamepad.timestamp, &ppapi_gamepad));
|
| + EXPECT_EQ(AddressDiff(&web_gamepad.axesLength, &web_gamepad),
|
| + AddressDiff(&ppapi_gamepad.axes_length, &ppapi_gamepad));
|
| + EXPECT_EQ(AddressDiff(&web_gamepad.axes, &web_gamepad),
|
| + AddressDiff(&ppapi_gamepad.axes, &ppapi_gamepad));
|
| + EXPECT_EQ(AddressDiff(&web_gamepad.buttonsLength, &web_gamepad),
|
| + AddressDiff(&ppapi_gamepad.buttons_length, &ppapi_gamepad));
|
| + EXPECT_EQ(AddressDiff(&web_gamepad.buttons, &web_gamepad),
|
| + AddressDiff(&ppapi_gamepad.buttons, &ppapi_gamepad));
|
| +}
|
| +
|
| +TEST_F(PepperGamepadHostTest, WaitForReply) {
|
| + WebKit::WebGamepads default_data;
|
| + memset(&default_data, 0, sizeof(WebKit::WebGamepads));
|
| + default_data.length = 1;
|
| + default_data.items[0].connected = true;
|
| + default_data.items[0].buttonsLength = 1;
|
| + ConstructService(default_data);
|
| +
|
| + PP_Instance pp_instance = 12345;
|
| + PP_Resource pp_resource = 67890;
|
| + PepperGamepadHost gamepad_host(gamepad_service(), GetPpapiHost(),
|
| + pp_instance, pp_resource);
|
| +
|
| + // Synthesize a request for gamepad data.
|
| + ppapi::host::HostMessageContext context(
|
| + ppapi::proxy::ResourceMessageCallParams(pp_resource, 1));
|
| + EXPECT_EQ(PP_OK_COMPLETIONPENDING,
|
| + gamepad_host.OnResourceMessageReceived(
|
| + PpapiHostMsg_Gamepad_RequestMemory(),
|
| + &context));
|
| +
|
| + // Wait for the gamepad background thread to read twice to make sure we
|
| + // don't get a message yet (see below for why).
|
| + MockGamepadDataFetcher* fetcher = service_->data_fetcher();
|
| + fetcher->WaitForDataRead();
|
| + fetcher->WaitForDataRead();
|
| +
|
| + // It should not have sent the callback message.
|
| + service_->message_loop().RunAllPending();
|
| + EXPECT_EQ(0u, sink().message_count());
|
| +
|
| + // Set a button down and wait for it to be read twice.
|
| + //
|
| + // We wait for two reads before calling RunAllPending because the provider
|
| + // will read the data on the background thread (setting the event) and *then*
|
| + // will issue the callback on our thread. Waiting for it to read twice
|
| + // ensures that it was able to issue callbacks for the first read (if it
|
| + // issued one) before we try to check for it.
|
| + WebKit::WebGamepads button_down_data = default_data;
|
| + button_down_data.items[0].buttons[0] = 1.f;
|
| + fetcher->SetTestData(button_down_data);
|
| + fetcher->WaitForDataRead();
|
| + fetcher->WaitForDataRead();
|
| +
|
| + // It should have sent a callback.
|
| + service_->message_loop().RunAllPending();
|
| + ppapi::proxy::ResourceMessageReplyParams reply_params;
|
| + IPC::Message reply_msg;
|
| + ASSERT_TRUE(sink().GetFirstResourceReplyMatching(
|
| + PpapiPluginMsg_Gamepad_SendMemory::ID, &reply_params, &reply_msg));
|
| +
|
| + // Extract the shared memory handle.
|
| + base::SharedMemoryHandle reply_handle;
|
| + EXPECT_TRUE(reply_params.GetSharedMemoryHandleAtIndex(0, &reply_handle));
|
| +
|
| + // Validate the shared memory.
|
| + base::SharedMemory shared_memory(reply_handle, true);
|
| + EXPECT_TRUE(shared_memory.Map(sizeof(ppapi::ContentGamepadHardwareBuffer)));
|
| + const ppapi::ContentGamepadHardwareBuffer* buffer =
|
| + static_cast<const ppapi::ContentGamepadHardwareBuffer*>(
|
| + shared_memory.memory());
|
| + EXPECT_EQ(button_down_data.length, buffer->buffer.length);
|
| + EXPECT_EQ(button_down_data.items[0].buttonsLength,
|
| + buffer->buffer.items[0].buttons_length);
|
| + for (size_t i = 0; i < ppapi::WebKitGamepad::kButtonsLengthCap; i++) {
|
| + EXPECT_EQ(button_down_data.items[0].buttons[i],
|
| + buffer->buffer.items[0].buttons[i]);
|
| + }
|
| +
|
| + // Duplicate requests should be denied.
|
| + EXPECT_EQ(PP_ERROR_FAILED,
|
| + gamepad_host.OnResourceMessageReceived(
|
| + PpapiHostMsg_Gamepad_RequestMemory(),
|
| + &context));
|
| +}
|
| +
|
| +} // namespace content
|
|
|