blob: 61e40743228dddb00bbca68e6d50114f0d9ddea6 [file] [log] [blame]
// 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 "content/browser/renderer_host/pepper/pepper_gamepad_host.h"
#include <stddef.h>
#include <string.h>
#include <memory>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_test.h"
#include "device/gamepad/gamepad_shared_buffer.h"
#include "device/gamepad/gamepad_test_helpers.h"
#include "device/gamepad/public/cpp/gamepads.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 "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
class PepperGamepadHostTest : public testing::Test,
public BrowserPpapiHostTest {
public:
PepperGamepadHostTest() {}
~PepperGamepadHostTest() override {}
void ConstructService(const device::Gamepads& test_data) {
service_.reset(new device::GamepadServiceTestConstructor(test_data));
}
device::GamepadService* gamepad_service() {
return service_->gamepad_service();
}
protected:
std::unique_ptr<device::GamepadServiceTestConstructor> service_;
DISALLOW_COPY_AND_ASSIGN(PepperGamepadHostTest);
};
} // namespace
TEST_F(PepperGamepadHostTest, WaitForReply) {
device::Gamepads default_data;
memset(&default_data, 0, sizeof(device::Gamepads));
default_data.items[0].connected = true;
default_data.items[0].buttons_length = 1;
ConstructService(default_data);
PP_Instance pp_instance = 12345;
PP_Resource pp_resource = 67890;
PepperGamepadHost gamepad_host(
gamepad_service(), GetBrowserPpapiHost(), 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));
device::MockGamepadDataFetcher* fetcher = service_->data_fetcher();
fetcher->WaitForDataReadAndCallbacksIssued();
// It should not have sent the callback message.
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, sink().message_count());
// Set a button down and wait for it to be read twice.
device::Gamepads button_down_data = default_data;
button_down_data.items[0].buttons[0].value = 1.f;
button_down_data.items[0].buttons[0].pressed = true;
fetcher->SetTestData(button_down_data);
fetcher->WaitForDataReadAndCallbacksIssued();
// It should have sent a callback.
base::RunLoop().RunUntilIdle();
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 region.
base::ReadOnlySharedMemoryRegion shared_memory_region;
EXPECT_TRUE(reply_params.TakeReadOnlySharedMemoryRegionAtIndex(
0, &shared_memory_region));
// Validate the shared memory.
base::ReadOnlySharedMemoryMapping shared_memory_mapping =
shared_memory_region.Map();
EXPECT_TRUE(shared_memory_mapping.IsValid());
const device::GamepadHardwareBuffer* buffer =
static_cast<const device::GamepadHardwareBuffer*>(
shared_memory_mapping.memory());
EXPECT_EQ(button_down_data.items[0].buttons_length,
buffer->data.items[0].buttons_length);
for (size_t i = 0; i < device::Gamepad::kButtonsLengthCap; i++) {
EXPECT_EQ(button_down_data.items[0].buttons[i].value,
buffer->data.items[0].buttons[i].value);
EXPECT_EQ(button_down_data.items[0].buttons[i].pressed,
buffer->data.items[0].buttons[i].pressed);
}
// Duplicate requests should be denied.
EXPECT_EQ(PP_ERROR_FAILED,
gamepad_host.OnResourceMessageReceived(
PpapiHostMsg_Gamepad_RequestMemory(), &context));
}
} // namespace content