123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- // 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 "device/gamepad/gamepad_provider.h"
- #include <memory>
- #include "base/bind.h"
- #include "base/command_line.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/weak_ptr.h"
- #include "base/run_loop.h"
- #include "base/threading/platform_thread.h"
- #include "base/threading/thread.h"
- #include "build/build_config.h"
- #include "device/gamepad/gamepad_data_fetcher.h"
- #include "device/gamepad/gamepad_test_helpers.h"
- #include "device/gamepad/public/cpp/gamepad_switches.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace device {
- namespace {
- // Helper class to generate and record user gesture callbacks.
- class UserGestureListener {
- public:
- UserGestureListener() : has_user_gesture_(false) {}
- base::OnceClosure GetClosure() {
- return base::BindOnce(&UserGestureListener::GotUserGesture,
- weak_factory_.GetWeakPtr());
- }
- bool has_user_gesture() const { return has_user_gesture_; }
- private:
- void GotUserGesture() { has_user_gesture_ = true; }
- bool has_user_gesture_;
- base::WeakPtrFactory<UserGestureListener> weak_factory_{this};
- };
- class TestChangeClient : public GamepadChangeClient {
- public:
- TestChangeClient() = default;
- TestChangeClient(const TestChangeClient&) = delete;
- TestChangeClient& operator=(const TestChangeClient&) = delete;
- ~TestChangeClient() = default;
- void OnGamepadConnectionChange(bool connected,
- uint32_t index,
- const Gamepad& pad) override {}
- void OnGamepadChange(mojom::GamepadChangesPtr changes) override {
- all_changes_.push_back(std::move(changes));
- EXPECT_GT(num_changes_left_, 0);
- if (--num_changes_left_ == 0)
- run_loop_.Quit();
- }
- void RunUntilChangeEvents(int num_changes) {
- // If we are explicitly not expecting any changes wait 20 milliseconds
- // to ensure no changes come in.
- if (num_changes == 0) {
- num_changes_left_ = 0;
- base::PlatformThread::Sleep(base::Milliseconds(20));
- base::RunLoop().RunUntilIdle();
- return;
- }
- num_changes_left_ = num_changes;
- run_loop_.Run();
- }
- const std::vector<mojom::GamepadChangesPtr>& all_changes() const {
- return all_changes_;
- }
- private:
- int num_changes_left_ = 0;
- base::RunLoop run_loop_;
- std::vector<mojom::GamepadChangesPtr> all_changes_;
- };
- // Main test fixture
- class GamepadProviderTest : public testing::Test, public GamepadTestHelper {
- public:
- GamepadProviderTest(const GamepadProviderTest&) = delete;
- GamepadProviderTest& operator=(const GamepadProviderTest&) = delete;
- GamepadProvider* CreateProvider(const Gamepads& test_data) {
- auto fetcher = std::make_unique<MockGamepadDataFetcher>(test_data);
- mock_data_fetcher_ = fetcher.get();
- provider_ =
- std::make_unique<GamepadProvider>(&change_client_, std::move(fetcher),
- /*polling_thread=*/nullptr);
- return provider_.get();
- }
- // Sleep until the shared memory buffer's seqlock advances the buffer version,
- // indicating that the gamepad provider has written to it after polling the
- // gamepad fetchers. The buffer will report an odd value for the version if
- // the buffer is not in a consistent state, so we also require that the value
- // is even before continuing.
- void WaitForData(const GamepadHardwareBuffer* buffer) {
- const base::subtle::Atomic32 initial_version = buffer->seqlock.ReadBegin();
- base::subtle::Atomic32 current_version;
- do {
- base::PlatformThread::Sleep(base::Milliseconds(10));
- current_version = buffer->seqlock.ReadBegin();
- } while (current_version % 2 || current_version == initial_version);
- }
- // The provider polls the data on the background thread and then issues
- // the callback on the client thread. Waiting for it to poll twice ensures
- // that it was able to issue callbacks for the first poll.
- void WaitForDataAndCallbacksIssued(const GamepadHardwareBuffer* buffer) {
- WaitForData(buffer);
- WaitForData(buffer);
- }
- void ReadGamepadHardwareBuffer(const GamepadHardwareBuffer* buffer,
- Gamepads* output) {
- memset(output, 0, sizeof(Gamepads));
- base::subtle::Atomic32 version;
- do {
- version = buffer->seqlock.ReadBegin();
- memcpy(output, &buffer->data, sizeof(Gamepads));
- } while (buffer->seqlock.ReadRetry(version));
- }
- protected:
- GamepadProviderTest() = default;
- std::unique_ptr<GamepadProvider> provider_;
- // Pointer owned by the provider.
- raw_ptr<MockGamepadDataFetcher> mock_data_fetcher_;
- TestChangeClient change_client_;
- };
- TEST_F(GamepadProviderTest, PollingAccess) {
- Gamepads test_data;
- memset(&test_data, 0, sizeof(Gamepads));
- test_data.items[0].connected = true;
- test_data.items[0].timestamp = 0;
- test_data.items[0].buttons_length = 1;
- test_data.items[0].axes_length = 2;
- test_data.items[0].buttons[0].value = 1.0f;
- test_data.items[0].buttons[0].pressed = true;
- test_data.items[0].axes[0] = -1.0f;
- test_data.items[0].axes[1] = 0.5f;
- GamepadProvider* provider = CreateProvider(test_data);
- provider->SetSanitizationEnabled(false);
- provider->Resume();
- base::RunLoop().RunUntilIdle();
- // Renderer-side, pull data out of poll buffer.
- base::ReadOnlySharedMemoryRegion region =
- provider->DuplicateSharedMemoryRegion();
- base::ReadOnlySharedMemoryMapping mapping = region.Map();
- EXPECT_TRUE(mapping.IsValid());
- const GamepadHardwareBuffer* buffer =
- static_cast<const GamepadHardwareBuffer*>(mapping.memory());
- // Wait until the shared memory buffer has been written at least once.
- WaitForData(buffer);
- Gamepads output;
- ReadGamepadHardwareBuffer(buffer, &output);
- ASSERT_EQ(1u, output.items[0].buttons_length);
- EXPECT_EQ(1.0f, output.items[0].buttons[0].value);
- EXPECT_EQ(true, output.items[0].buttons[0].pressed);
- ASSERT_EQ(2u, output.items[0].axes_length);
- EXPECT_EQ(-1.0f, output.items[0].axes[0]);
- EXPECT_EQ(0.5f, output.items[0].axes[1]);
- }
- TEST_F(GamepadProviderTest, ConnectDisconnectMultiple) {
- Gamepads test_data;
- test_data.items[0].connected = true;
- test_data.items[0].timestamp = 0;
- test_data.items[0].axes_length = 2;
- test_data.items[0].axes[0] = -1.0f;
- test_data.items[0].axes[1] = 0.5f;
- test_data.items[1].connected = true;
- test_data.items[1].timestamp = 0;
- test_data.items[1].axes_length = 2;
- test_data.items[1].axes[0] = 1.0f;
- test_data.items[1].axes[1] = -0.5f;
- Gamepads test_data_onedisconnected;
- test_data_onedisconnected.items[1].connected = true;
- test_data_onedisconnected.items[1].timestamp = 0;
- test_data_onedisconnected.items[1].axes_length = 2;
- test_data_onedisconnected.items[1].axes[0] = 1.0f;
- test_data_onedisconnected.items[1].axes[1] = -0.5f;
- GamepadProvider* provider = CreateProvider(test_data);
- provider->SetSanitizationEnabled(false);
- provider->Resume();
- base::RunLoop().RunUntilIdle();
- // Renderer-side, pull data out of poll buffer.
- base::ReadOnlySharedMemoryRegion region =
- provider->DuplicateSharedMemoryRegion();
- base::ReadOnlySharedMemoryMapping mapping = region.Map();
- EXPECT_TRUE(mapping.IsValid());
- const GamepadHardwareBuffer* buffer =
- static_cast<const GamepadHardwareBuffer*>(mapping.memory());
- // Wait until the shared memory buffer has been written at least once.
- WaitForData(buffer);
- Gamepads output;
- ReadGamepadHardwareBuffer(buffer, &output);
- ASSERT_EQ(2u, output.items[0].axes_length);
- EXPECT_EQ(-1.0f, output.items[0].axes[0]);
- EXPECT_EQ(0.5f, output.items[0].axes[1]);
- ASSERT_EQ(2u, output.items[1].axes_length);
- EXPECT_EQ(1.0f, output.items[1].axes[0]);
- EXPECT_EQ(-0.5f, output.items[1].axes[1]);
- mock_data_fetcher_->SetTestData(test_data_onedisconnected);
- WaitForDataAndCallbacksIssued(buffer);
- ReadGamepadHardwareBuffer(buffer, &output);
- EXPECT_EQ(0u, output.items[0].axes_length);
- ASSERT_EQ(2u, output.items[1].axes_length);
- EXPECT_EQ(1.0f, output.items[1].axes[0]);
- EXPECT_EQ(-0.5f, output.items[1].axes[1]);
- }
- // Tests that waiting for a user gesture works properly.
- TEST_F(GamepadProviderTest, UserGesture) {
- Gamepads no_button_data;
- no_button_data.items[0].connected = true;
- no_button_data.items[0].timestamp = 0;
- no_button_data.items[0].buttons_length = 1;
- no_button_data.items[0].axes_length = 2;
- no_button_data.items[0].buttons[0].value = 0.0f;
- no_button_data.items[0].buttons[0].pressed = false;
- no_button_data.items[0].axes[0] = 0.0f;
- no_button_data.items[0].axes[1] = 0.4f;
- Gamepads button_down_data = no_button_data;
- button_down_data.items[0].buttons[0].value = 1.0f;
- button_down_data.items[0].buttons[0].pressed = true;
- UserGestureListener listener;
- GamepadProvider* provider = CreateProvider(no_button_data);
- provider->SetSanitizationEnabled(false);
- provider->Resume();
- provider->RegisterForUserGesture(listener.GetClosure());
- base::RunLoop().RunUntilIdle();
- // Renderer-side, pull data out of poll buffer.
- base::ReadOnlySharedMemoryRegion region =
- provider->DuplicateSharedMemoryRegion();
- base::ReadOnlySharedMemoryMapping mapping = region.Map();
- EXPECT_TRUE(mapping.IsValid());
- const GamepadHardwareBuffer* buffer =
- static_cast<const GamepadHardwareBuffer*>(mapping.memory());
- // Wait until the shared memory buffer has been written at least once.
- WaitForData(buffer);
- // It should not have issued our callback.
- EXPECT_FALSE(listener.has_user_gesture());
- // Set a button down.
- mock_data_fetcher_->SetTestData(button_down_data);
- // The user gesture listener callback is not called until after the buffer has
- // been updated. Wait for the second update to ensure callbacks have fired.
- WaitForDataAndCallbacksIssued(buffer);
- // It should have issued our callback.
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(listener.has_user_gesture());
- }
- // Tests that waiting for a user gesture works properly.
- TEST_F(GamepadProviderTest, Sanitization) {
- Gamepads active_data;
- active_data.items[0].connected = true;
- active_data.items[0].timestamp = 0;
- active_data.items[0].buttons_length = 1;
- active_data.items[0].axes_length = 1;
- active_data.items[0].buttons[0].value = 1.0f;
- active_data.items[0].buttons[0].pressed = true;
- active_data.items[0].axes[0] = -1.0f;
- Gamepads zero_data;
- zero_data.items[0].connected = true;
- zero_data.items[0].timestamp = 0;
- zero_data.items[0].buttons_length = 1;
- zero_data.items[0].axes_length = 1;
- zero_data.items[0].buttons[0].value = 0.0f;
- zero_data.items[0].buttons[0].pressed = false;
- zero_data.items[0].axes[0] = 0.0f;
- UserGestureListener listener;
- GamepadProvider* provider = CreateProvider(active_data);
- provider->SetSanitizationEnabled(true);
- provider->Resume();
- base::RunLoop().RunUntilIdle();
- // Renderer-side, pull data out of poll buffer.
- base::ReadOnlySharedMemoryRegion region =
- provider->DuplicateSharedMemoryRegion();
- base::ReadOnlySharedMemoryMapping mapping = region.Map();
- ASSERT_TRUE(mapping.IsValid());
- const GamepadHardwareBuffer* buffer =
- static_cast<const GamepadHardwareBuffer*>(mapping.memory());
- // Wait until the shared memory buffer has been written at least once.
- WaitForData(buffer);
- Gamepads output;
- ReadGamepadHardwareBuffer(buffer, &output);
- // Initial data should all be zeroed out due to sanitization, even though the
- // gamepad reported input
- ASSERT_EQ(1u, output.items[0].buttons_length);
- EXPECT_EQ(0.0f, output.items[0].buttons[0].value);
- EXPECT_FALSE(output.items[0].buttons[0].pressed);
- ASSERT_EQ(1u, output.items[0].axes_length);
- EXPECT_EQ(0.0f, output.items[0].axes[0]);
- // Zero out the inputs
- mock_data_fetcher_->SetTestData(zero_data);
- WaitForDataAndCallbacksIssued(buffer);
- // Read updated data from shared memory
- ReadGamepadHardwareBuffer(buffer, &output);
- // Should still read zero, which is now an accurate reflection of the data
- ASSERT_EQ(1u, output.items[0].buttons_length);
- EXPECT_EQ(0.0f, output.items[0].buttons[0].value);
- EXPECT_FALSE(output.items[0].buttons[0].pressed);
- ASSERT_EQ(1u, output.items[0].axes_length);
- EXPECT_EQ(0.0f, output.items[0].axes[0]);
- // Re-set the active inputs
- mock_data_fetcher_->SetTestData(active_data);
- WaitForDataAndCallbacksIssued(buffer);
- // Read updated data from shared memory
- ReadGamepadHardwareBuffer(buffer, &output);
- // Should now accurately reflect the reported data.
- ASSERT_EQ(1u, output.items[0].buttons_length);
- EXPECT_EQ(1.0f, output.items[0].buttons[0].value);
- EXPECT_TRUE(output.items[0].buttons[0].pressed);
- ASSERT_EQ(1u, output.items[0].axes_length);
- EXPECT_EQ(-1.0f, output.items[0].axes[0]);
- }
- TEST_F(GamepadProviderTest, SendEvents) {
- // This is a test for the logic that is currently behind this flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableGamepadButtonAxisEvents);
- Gamepads test_data;
- test_data.items[0].connected = true;
- test_data.items[0].timestamp = 0;
- test_data.items[0].axes_length = 2;
- test_data.items[0].axes[0] = -1.0f;
- test_data.items[0].axes[1] = 0.5f;
- test_data.items[0].buttons[0].value = 0.0f;
- test_data.items[0].buttons[0].pressed = false;
- test_data.items[0].buttons[1].value = 0.7f;
- test_data.items[0].buttons[1].pressed = true;
- test_data.items[0].buttons[2].value = 0.0f;
- test_data.items[0].buttons[2].pressed = false;
- test_data.items[0].buttons[3].value = 0.0f;
- test_data.items[0].buttons[3].pressed = false;
- test_data.items[0].buttons_length = 4;
- test_data.items[0].axes_length = 2;
- test_data.items[1].connected = true;
- test_data.items[1].timestamp = 0;
- test_data.items[1].axes_length = 2;
- test_data.items[1].axes[0] = 1.0f;
- test_data.items[1].axes[1] = -0.5f;
- test_data.items[1].buttons[0].value = 0.0f;
- test_data.items[1].buttons[0].pressed = false;
- test_data.items[1].buttons[1].value = 1.0f;
- test_data.items[1].buttons[1].pressed = true;
- test_data.items[1].buttons[2].value = 1.0f;
- test_data.items[1].buttons[2].pressed = true;
- test_data.items[1].buttons_length = 3;
- test_data.items[1].axes_length = 2;
- Gamepads test_data_changed = test_data;
- test_data_changed.items[0].axes[1] = -0.5f;
- test_data_changed.items[0].buttons[0].value = 0.4f;
- test_data_changed.items[0].buttons[1].value = 0.2f;
- test_data_changed.items[0].buttons[1].pressed = false;
- test_data_changed.items[0].buttons[3].value = 0.2f;
- test_data_changed.items[1].axes[0] = 0.5f;
- test_data_changed.items[1].buttons[0].value = 1.0f;
- test_data_changed.items[1].buttons[0].pressed = true;
- test_data_changed.items[1].buttons[2].value = 0.9f;
- GamepadProvider* provider = CreateProvider(test_data);
- provider->SetSanitizationEnabled(false);
- provider->Resume();
- base::RunLoop().RunUntilIdle();
- // Renderer-side, pull data out of poll buffer.
- base::ReadOnlySharedMemoryRegion region =
- provider->DuplicateSharedMemoryRegion();
- base::ReadOnlySharedMemoryMapping mapping = region.Map();
- EXPECT_TRUE(mapping.IsValid());
- const GamepadHardwareBuffer* buffer =
- static_cast<const GamepadHardwareBuffer*>(mapping.memory());
- // Wait until the shared memory buffer has been written at least once.
- WaitForData(buffer);
- mock_data_fetcher_->SetTestData(test_data_changed);
- // Wait for changes to take place and events to fire.
- WaitForDataAndCallbacksIssued(buffer);
- change_client_.RunUntilChangeEvents(2);
- const auto& changes = change_client_.all_changes();
- // Ensure the |button_changes| and |axis_changes| objects have all the
- // expected values.
- ASSERT_EQ(2u, changes.size());
- ASSERT_EQ(1u, changes[1]->axis_changes.size());
- ASSERT_EQ(1u, changes[0]->axis_changes.size());
- ASSERT_EQ(2u, changes[1]->button_changes.size());
- ASSERT_EQ(3u, changes[0]->button_changes.size());
- EXPECT_EQ(1u, changes[0]->axis_changes[0]->axis_index);
- EXPECT_EQ(-0.5f, changes[0]->axis_changes[0]->axis_snapshot);
- EXPECT_EQ(0u, changes[0]->button_changes[0]->button_index);
- EXPECT_FALSE(changes[0]->button_changes[0]->button_up);
- EXPECT_FALSE(changes[0]->button_changes[0]->button_down);
- EXPECT_TRUE(changes[0]->button_changes[0]->value_changed);
- EXPECT_EQ(changes[0]->button_changes[0]->button_snapshot,
- test_data_changed.items[0].buttons[0]);
- EXPECT_EQ(1u, changes[0]->button_changes[1]->button_index);
- EXPECT_TRUE(changes[0]->button_changes[1]->button_up);
- EXPECT_FALSE(changes[0]->button_changes[1]->button_down);
- EXPECT_TRUE(changes[0]->button_changes[1]->value_changed);
- EXPECT_EQ(changes[0]->button_changes[1]->button_snapshot,
- test_data_changed.items[0].buttons[1]);
- EXPECT_EQ(3u, changes[0]->button_changes[2]->button_index);
- EXPECT_FALSE(changes[0]->button_changes[2]->button_up);
- EXPECT_FALSE(changes[0]->button_changes[2]->button_down);
- EXPECT_TRUE(changes[0]->button_changes[2]->value_changed);
- EXPECT_EQ(changes[0]->button_changes[2]->button_snapshot,
- test_data_changed.items[0].buttons[3]);
- EXPECT_EQ(0u, changes[1]->axis_changes[0]->axis_index);
- EXPECT_EQ(0.5f, changes[1]->axis_changes[0]->axis_snapshot);
- EXPECT_EQ(0u, changes[1]->button_changes[0]->button_index);
- EXPECT_FALSE(changes[1]->button_changes[0]->button_up);
- EXPECT_TRUE(changes[1]->button_changes[0]->button_down);
- EXPECT_TRUE(changes[1]->button_changes[0]->value_changed);
- EXPECT_EQ(changes[1]->button_changes[0]->button_snapshot,
- test_data_changed.items[1].buttons[0]);
- EXPECT_EQ(2u, changes[1]->button_changes[1]->button_index);
- EXPECT_FALSE(changes[1]->button_changes[1]->button_up);
- EXPECT_FALSE(changes[1]->button_changes[1]->button_down);
- EXPECT_TRUE(changes[1]->button_changes[1]->value_changed);
- EXPECT_EQ(changes[1]->button_changes[1]->button_snapshot,
- test_data_changed.items[1].buttons[2]);
- }
- TEST_F(GamepadProviderTest, DontSendEventsBeforeUserGesture) {
- // This is a test for the logic that is currently behind this flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableGamepadButtonAxisEvents);
- Gamepads test_data;
- test_data.items[0].connected = true;
- test_data.items[0].timestamp = 0;
- test_data.items[0].axes_length = 2;
- test_data.items[0].axes[0] = 0.0f;
- test_data.items[0].buttons[0].value = 0.0f;
- test_data.items[0].buttons[0].pressed = false;
- test_data.items[0].buttons_length = 1;
- test_data.items[0].axes_length = 1;
- Gamepads test_data_changed = test_data;
- test_data_changed.items[0].axes[1] = 0.4f;
- test_data_changed.items[0].buttons[0].value = 0.3f;
- GamepadProvider* provider = CreateProvider(test_data);
- provider->SetSanitizationEnabled(false);
- provider->Resume();
- base::RunLoop().RunUntilIdle();
- // Renderer-side, pull data out of poll buffer.
- base::ReadOnlySharedMemoryRegion region =
- provider->DuplicateSharedMemoryRegion();
- base::ReadOnlySharedMemoryMapping mapping = region.Map();
- EXPECT_TRUE(mapping.IsValid());
- const GamepadHardwareBuffer* buffer =
- static_cast<const GamepadHardwareBuffer*>(mapping.memory());
- // Wait until the shared memory buffer has been written at least once.
- WaitForData(buffer);
- mock_data_fetcher_->SetTestData(test_data_changed);
- // Wait for changes to take place and allow potential events to fire.
- WaitForDataAndCallbacksIssued(buffer);
- change_client_.RunUntilChangeEvents(0);
- EXPECT_TRUE(change_client_.all_changes().empty());
- }
- TEST_F(GamepadProviderTest, DontSendEventsWhenDisconnected) {
- // This is a test for the logic that is currently behind this flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableGamepadButtonAxisEvents);
- Gamepads test_data;
- test_data.items[0].connected = false;
- test_data.items[0].timestamp = 0;
- test_data.items[0].axes[0] = 0.0f;
- test_data.items[0].buttons[0].value = 1.0f;
- test_data.items[0].buttons[0].pressed = true;
- test_data.items[0].buttons_length = 1;
- test_data.items[0].axes_length = 1;
- test_data.items[1].connected = true;
- test_data.items[1].timestamp = 0;
- test_data.items[1].axes[0] = 1.0f;
- test_data.items[1].buttons[0].value = 0.0f;
- test_data.items[1].buttons[0].pressed = false;
- test_data.items[1].buttons_length = 1;
- test_data.items[1].axes_length = 1;
- Gamepads test_data_changed = test_data;
- test_data_changed.items[0].axes[0] = 1.0f;
- test_data_changed.items[0].buttons[0].value = 0.0f;
- test_data_changed.items[0].buttons[0].pressed = false;
- test_data_changed.items[1].connected = false;
- test_data_changed.items[1].axes[0] = 0.0f;
- test_data_changed.items[1].buttons[0].value = 1.0f;
- test_data_changed.items[1].buttons[0].pressed = true;
- GamepadProvider* provider = CreateProvider(test_data);
- provider->SetSanitizationEnabled(false);
- provider->Resume();
- base::RunLoop().RunUntilIdle();
- // Renderer-side, pull data out of poll buffer.
- base::ReadOnlySharedMemoryRegion region =
- provider->DuplicateSharedMemoryRegion();
- base::ReadOnlySharedMemoryMapping mapping = region.Map();
- EXPECT_TRUE(mapping.IsValid());
- const GamepadHardwareBuffer* buffer =
- static_cast<const GamepadHardwareBuffer*>(mapping.memory());
- // Wait until the shared memory buffer has been written at least once.
- WaitForData(buffer);
- mock_data_fetcher_->SetTestData(test_data_changed);
- // Wait for changes to take place and allow potential events to fire.
- WaitForDataAndCallbacksIssued(buffer);
- change_client_.RunUntilChangeEvents(0);
- EXPECT_TRUE(change_client_.all_changes().empty());
- }
- TEST_F(GamepadProviderTest, DontSendEventsOnConnection) {
- // This is a test for the logic that is currently behind this flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableGamepadButtonAxisEvents);
- Gamepads test_data;
- test_data.items[0].connected = true;
- test_data.items[0].timestamp = 0;
- test_data.items[0].axes[0] = 0.0f;
- test_data.items[0].buttons[0].value = 1.0f;
- test_data.items[0].buttons[0].pressed = true;
- test_data.items[0].buttons_length = 1;
- test_data.items[0].axes_length = 1;
- test_data.items[1].connected = false;
- test_data.items[1].timestamp = 0;
- test_data.items[1].axes[0] = 0.0f;
- test_data.items[1].buttons[0].value = 1.0f;
- test_data.items[1].buttons[0].pressed = true;
- test_data.items[1].buttons_length = 1;
- test_data.items[1].axes_length = 1;
- Gamepads test_data_changed = test_data;
- test_data_changed.items[1].connected = true;
- test_data_changed.items[1].axes[0] = 1.0f;
- test_data_changed.items[1].buttons[0].value = 0.0f;
- test_data_changed.items[1].buttons[0].pressed = false;
- GamepadProvider* provider = CreateProvider(test_data);
- provider->SetSanitizationEnabled(false);
- provider->Resume();
- base::RunLoop().RunUntilIdle();
- // Renderer-side, pull data out of poll buffer.
- base::ReadOnlySharedMemoryRegion region =
- provider->DuplicateSharedMemoryRegion();
- base::ReadOnlySharedMemoryMapping mapping = region.Map();
- EXPECT_TRUE(mapping.IsValid());
- const GamepadHardwareBuffer* buffer =
- static_cast<const GamepadHardwareBuffer*>(mapping.memory());
- // Wait until the shared memory buffer has been written at least once.
- WaitForData(buffer);
- mock_data_fetcher_->SetTestData(test_data_changed);
- // Wait for changes to take place and allow potential events to fire.
- WaitForDataAndCallbacksIssued(buffer);
- change_client_.RunUntilChangeEvents(0);
- EXPECT_TRUE(change_client_.all_changes().empty());
- }
- } // namespace
- } // namespace device
|