mirror of
https://github.com/LizardByte/libvirtualhid.git
synced 2026-10-25 12:37:02 +09:00
570 lines
17 KiB
C++
570 lines
17 KiB
C++
/**
|
|
* @file tests/unit/test_profiles.cpp
|
|
* @brief Unit tests for built-in gamepad profiles.
|
|
*/
|
|
|
|
// standard includes
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
// local includes
|
|
#include "fixtures/fixtures.hpp"
|
|
|
|
#include <libvirtualhid/profiles.hpp>
|
|
#include <libvirtualhid/report.hpp>
|
|
|
|
namespace {
|
|
struct PackedButtonCase {
|
|
lvh::GamepadButton button;
|
|
std::uint16_t bit;
|
|
};
|
|
|
|
struct PackedByteButtonCase {
|
|
lvh::GamepadButton button;
|
|
std::size_t offset;
|
|
std::uint8_t mask;
|
|
};
|
|
|
|
template<std::size_t Size>
|
|
void expect_descriptor_contains(
|
|
const lvh::DeviceProfile &profile,
|
|
const std::array<std::uint8_t, Size> &expected
|
|
) {
|
|
const auto match = std::ranges::search(profile.report_descriptor, expected);
|
|
EXPECT_NE(match.begin(), profile.report_descriptor.end());
|
|
}
|
|
|
|
std::uint16_t read_u16_le(const std::vector<std::uint8_t> &report, std::size_t offset) {
|
|
const auto low = std::byte {report[offset]};
|
|
const auto high = std::byte {report[offset + 1U]};
|
|
return static_cast<std::uint16_t>(
|
|
std::to_integer<std::uint16_t>(low) | (std::to_integer<std::uint16_t>(high) << 8U)
|
|
);
|
|
}
|
|
|
|
void expect_packed_button_bits(
|
|
const lvh::DeviceProfile &profile,
|
|
const std::vector<PackedButtonCase> &button_cases,
|
|
std::size_t report_offset
|
|
) {
|
|
for (const auto &[button, bit] : button_cases) {
|
|
lvh::GamepadState state;
|
|
state.buttons.set(button);
|
|
const auto report = lvh::reports::pack_input_report(profile, state);
|
|
|
|
ASSERT_GT(report.size(), report_offset + 1U);
|
|
EXPECT_EQ(read_u16_le(report, report_offset), static_cast<std::uint16_t>(1U << bit))
|
|
<< "logical button " << static_cast<unsigned>(std::to_underlying(button));
|
|
}
|
|
}
|
|
} // namespace
|
|
|
|
TEST(ProfileTest, BuiltInProfilesHaveDescriptors) {
|
|
const auto profiles = lvh::profiles::built_in_gamepad_profiles();
|
|
|
|
ASSERT_GE(profiles.size(), 4U);
|
|
for (const auto &profile : profiles) {
|
|
EXPECT_EQ(profile.device_type, lvh::DeviceType::gamepad);
|
|
EXPECT_FALSE(profile.name.empty());
|
|
EXPECT_NE(profile.vendor_id, 0);
|
|
EXPECT_NE(profile.product_id, 0);
|
|
EXPECT_GE(profile.input_report_size, 9U);
|
|
EXPECT_FALSE(profile.report_descriptor.empty());
|
|
}
|
|
}
|
|
|
|
TEST(ProfileTest, BuiltInProfilesUseDefaultDeviceNames) {
|
|
EXPECT_EQ(lvh::profiles::generic_gamepad().name, "(libvirtualhid) Generic Controller");
|
|
EXPECT_EQ(lvh::profiles::xbox_360().name, "(libvirtualhid) X-Box 360 Controller");
|
|
EXPECT_EQ(lvh::profiles::xbox_one().name, "(libvirtualhid) X-Box One Controller");
|
|
EXPECT_EQ(lvh::profiles::xbox_series().name, "(libvirtualhid) X-Box Series Controller");
|
|
EXPECT_EQ(lvh::profiles::dualshock4().name, "(libvirtualhid) PS4 Controller");
|
|
EXPECT_EQ(lvh::profiles::dualsense().name, "(libvirtualhid) PS5 Controller");
|
|
EXPECT_EQ(lvh::profiles::switch_pro().name, "(libvirtualhid) Nintendo Pro Controller");
|
|
}
|
|
|
|
TEST(ProfileTest, StreamingControllerProfilesArePresent) {
|
|
const auto xbox_one = lvh::profiles::xbox_one();
|
|
const auto dualshock4 = lvh::profiles::dualshock4();
|
|
const auto dualsense = lvh::profiles::dualsense();
|
|
const auto switch_pro = lvh::profiles::switch_pro();
|
|
|
|
EXPECT_EQ(xbox_one.vendor_id, 0x045E);
|
|
EXPECT_EQ(xbox_one.product_id, 0x02EA);
|
|
EXPECT_EQ(xbox_one.bus_type, lvh::BusType::usb);
|
|
EXPECT_EQ(xbox_one.manufacturer, "Microsoft");
|
|
EXPECT_TRUE(xbox_one.capabilities.supports_rumble);
|
|
EXPECT_TRUE(xbox_one.capabilities.supports_trigger_rumble);
|
|
EXPECT_TRUE(xbox_one.capabilities.supports_battery);
|
|
EXPECT_EQ(xbox_one.report_id, 0);
|
|
EXPECT_EQ(xbox_one.input_report_size, 17U);
|
|
EXPECT_EQ(xbox_one.output_report_size, 8U);
|
|
|
|
const auto xbox_series = lvh::profiles::xbox_series();
|
|
EXPECT_EQ(xbox_series.vendor_id, 0x045E);
|
|
EXPECT_EQ(xbox_series.product_id, 0x0B12);
|
|
EXPECT_EQ(xbox_series.bus_type, lvh::BusType::usb);
|
|
EXPECT_EQ(xbox_series.manufacturer, "Microsoft");
|
|
EXPECT_EQ(xbox_series.report_id, 0);
|
|
EXPECT_EQ(xbox_series.input_report_size, 17U);
|
|
EXPECT_EQ(xbox_series.output_report_size, 8U);
|
|
EXPECT_TRUE(xbox_series.capabilities.supports_trigger_rumble);
|
|
EXPECT_TRUE(xbox_series.capabilities.supports_battery);
|
|
|
|
const std::array<std::uint8_t, 11> xbox_gip_stick_axis_descriptor {
|
|
0x15,
|
|
0x00,
|
|
0x27,
|
|
0xFF,
|
|
0xFF,
|
|
0x00,
|
|
0x00,
|
|
0x95,
|
|
0x02,
|
|
0x75,
|
|
0x10,
|
|
};
|
|
EXPECT_TRUE(
|
|
std::ranges::search(xbox_one.report_descriptor, xbox_gip_stick_axis_descriptor).begin() != xbox_one.report_descriptor.end()
|
|
);
|
|
|
|
const std::array<std::uint8_t, 9> right_stick_usage_descriptor {
|
|
0x09,
|
|
0x33,
|
|
0x09,
|
|
0x34,
|
|
0x15,
|
|
0x00,
|
|
0x27,
|
|
0xFF,
|
|
0xFF,
|
|
};
|
|
EXPECT_TRUE(
|
|
std::ranges::search(xbox_one.report_descriptor, right_stick_usage_descriptor).begin() != xbox_one.report_descriptor.end()
|
|
);
|
|
|
|
const std::array<std::uint8_t, 9> trigger_usage_descriptor {
|
|
0x09,
|
|
0x32,
|
|
0x15,
|
|
0x00,
|
|
0x26,
|
|
0xFF,
|
|
0x03,
|
|
0x95,
|
|
0x01,
|
|
};
|
|
EXPECT_TRUE(
|
|
std::ranges::search(xbox_one.report_descriptor, trigger_usage_descriptor).begin() != xbox_one.report_descriptor.end()
|
|
);
|
|
|
|
const std::array<std::uint8_t, 9> right_trigger_usage_descriptor {
|
|
0x09,
|
|
0x35,
|
|
0x15,
|
|
0x00,
|
|
0x26,
|
|
0xFF,
|
|
0x03,
|
|
0x95,
|
|
0x01,
|
|
};
|
|
EXPECT_TRUE(
|
|
std::ranges::search(xbox_one.report_descriptor, right_trigger_usage_descriptor).begin() != xbox_one.report_descriptor.end()
|
|
);
|
|
|
|
EXPECT_EQ(dualshock4.vendor_id, 0x054C);
|
|
EXPECT_EQ(dualshock4.product_id, 0x05C4);
|
|
EXPECT_EQ(dualshock4.version, 0x0100);
|
|
EXPECT_EQ(dualshock4.bus_type, lvh::BusType::bluetooth);
|
|
EXPECT_EQ(dualshock4.report_id, 0x11);
|
|
EXPECT_EQ(dualshock4.input_report_size, 78U);
|
|
EXPECT_EQ(dualshock4.output_report_size, 78U);
|
|
EXPECT_TRUE(dualshock4.capabilities.supports_motion);
|
|
EXPECT_TRUE(dualshock4.capabilities.supports_touchpad);
|
|
EXPECT_TRUE(dualshock4.capabilities.supports_rgb_led);
|
|
EXPECT_TRUE(dualshock4.capabilities.supports_battery);
|
|
EXPECT_FALSE(dualshock4.capabilities.supports_adaptive_triggers);
|
|
EXPECT_EQ(dualshock4.manufacturer, "Sony Computer Entertainment");
|
|
|
|
const auto dualshock4_bluetooth = lvh::profiles::dualshock4_bluetooth();
|
|
EXPECT_EQ(dualshock4_bluetooth.bus_type, lvh::BusType::bluetooth);
|
|
EXPECT_EQ(dualshock4_bluetooth.version, 0x0100);
|
|
EXPECT_EQ(dualshock4_bluetooth.name, "(libvirtualhid) PS4 Controller");
|
|
EXPECT_EQ(dualshock4_bluetooth.manufacturer, "Sony Computer Entertainment");
|
|
EXPECT_EQ(dualshock4_bluetooth.report_id, 0x11);
|
|
EXPECT_EQ(dualshock4_bluetooth.input_report_size, 78U);
|
|
EXPECT_EQ(dualshock4_bluetooth.output_report_size, 78U);
|
|
EXPECT_EQ(dualshock4_bluetooth.report_descriptor, dualshock4.report_descriptor);
|
|
|
|
const auto dualshock4_usb = lvh::profiles::dualshock4_usb();
|
|
EXPECT_EQ(dualshock4_usb.bus_type, lvh::BusType::usb);
|
|
EXPECT_EQ(dualshock4_usb.report_id, 0x01);
|
|
EXPECT_EQ(dualshock4_usb.input_report_size, 64U);
|
|
EXPECT_EQ(dualshock4_usb.output_report_size, 32U);
|
|
EXPECT_NE(dualshock4_usb.report_descriptor, dualshock4.report_descriptor);
|
|
|
|
EXPECT_EQ(dualsense.vendor_id, 0x054C);
|
|
EXPECT_EQ(dualsense.bus_type, lvh::BusType::bluetooth);
|
|
EXPECT_EQ(dualsense.report_id, 0x31);
|
|
EXPECT_EQ(dualsense.input_report_size, 78U);
|
|
EXPECT_EQ(dualsense.output_report_size, 78U);
|
|
EXPECT_TRUE(dualsense.capabilities.supports_motion);
|
|
EXPECT_TRUE(dualsense.capabilities.supports_touchpad);
|
|
EXPECT_TRUE(dualsense.capabilities.supports_rgb_led);
|
|
EXPECT_TRUE(dualsense.capabilities.supports_adaptive_triggers);
|
|
EXPECT_GT(dualsense.input_report_size, 14U);
|
|
EXPECT_GT(dualsense.output_report_size, 5U);
|
|
EXPECT_EQ(dualsense.manufacturer, "Sony Interactive Entertainment");
|
|
|
|
const auto dualsense_bluetooth = lvh::profiles::dualsense_bluetooth();
|
|
EXPECT_EQ(dualsense_bluetooth.bus_type, lvh::BusType::bluetooth);
|
|
EXPECT_EQ(dualsense_bluetooth.name, "(libvirtualhid) PS5 Controller");
|
|
EXPECT_EQ(dualsense_bluetooth.report_id, 0x31);
|
|
EXPECT_EQ(dualsense_bluetooth.input_report_size, 78U);
|
|
EXPECT_EQ(dualsense_bluetooth.output_report_size, 78U);
|
|
EXPECT_EQ(dualsense_bluetooth.report_descriptor, dualsense.report_descriptor);
|
|
|
|
const auto dualsense_usb = lvh::profiles::dualsense_usb();
|
|
EXPECT_EQ(dualsense_usb.bus_type, lvh::BusType::usb);
|
|
EXPECT_EQ(dualsense_usb.report_id, 0x01);
|
|
EXPECT_EQ(dualsense_usb.input_report_size, 64U);
|
|
EXPECT_EQ(dualsense_usb.output_report_size, 48U);
|
|
EXPECT_NE(dualsense_usb.report_descriptor, dualsense.report_descriptor);
|
|
|
|
EXPECT_EQ(switch_pro.vendor_id, 0x057E);
|
|
EXPECT_EQ(switch_pro.product_id, 0x2009);
|
|
EXPECT_EQ(switch_pro.version, 0x0210);
|
|
EXPECT_EQ(switch_pro.manufacturer, "Nintendo Co., Ltd.");
|
|
EXPECT_EQ(switch_pro.report_id, 0x30);
|
|
EXPECT_EQ(switch_pro.input_report_size, 64U);
|
|
EXPECT_EQ(switch_pro.output_report_size, 64U);
|
|
EXPECT_TRUE(switch_pro.capabilities.supports_rumble);
|
|
EXPECT_TRUE(switch_pro.capabilities.supports_motion);
|
|
EXPECT_TRUE(switch_pro.capabilities.supports_rgb_led);
|
|
EXPECT_TRUE(switch_pro.capabilities.supports_battery);
|
|
|
|
const auto generic = lvh::profiles::generic_gamepad();
|
|
const std::array<std::uint8_t, 16> standard_button_descriptor {
|
|
0x05,
|
|
0x09, // Usage Page (Button)
|
|
0x19,
|
|
0x01, // Usage Minimum (Button 1)
|
|
0x29,
|
|
0x10, // Usage Maximum (Button 16)
|
|
0x15,
|
|
0x00,
|
|
0x25,
|
|
0x01,
|
|
0x75,
|
|
0x01,
|
|
0x95,
|
|
0x10,
|
|
0x81,
|
|
0x02,
|
|
};
|
|
EXPECT_TRUE(
|
|
std::ranges::search(generic.report_descriptor, standard_button_descriptor).begin() != generic.report_descriptor.end()
|
|
);
|
|
|
|
const std::array<std::uint8_t, 12> standard_axis_order {
|
|
0x09,
|
|
0x30,
|
|
0x09,
|
|
0x31,
|
|
0x09,
|
|
0x33,
|
|
0x09,
|
|
0x34,
|
|
0x09,
|
|
0x32,
|
|
0x09,
|
|
0x35,
|
|
};
|
|
EXPECT_TRUE(
|
|
std::ranges::search(generic.report_descriptor, standard_axis_order).begin() != generic.report_descriptor.end()
|
|
);
|
|
EXPECT_NE(switch_pro.report_descriptor, generic.report_descriptor);
|
|
|
|
const std::array<std::uint8_t, 2> switch_pro_report_id_descriptor {0x85, 0x30};
|
|
EXPECT_TRUE(
|
|
std::ranges::search(switch_pro.report_descriptor, switch_pro_report_id_descriptor).begin() !=
|
|
switch_pro.report_descriptor.end()
|
|
);
|
|
}
|
|
|
|
TEST(ProfileTest, NativeControllerDescriptorsUseContiguousButtonUsages) {
|
|
const auto xbox_one = lvh::profiles::xbox_one();
|
|
const auto xbox_series = lvh::profiles::xbox_series();
|
|
const auto switch_pro = lvh::profiles::switch_pro();
|
|
|
|
constexpr std::array<std::uint8_t, 12> xbox_one_buttons {
|
|
0x05,
|
|
0x09,
|
|
0x19,
|
|
0x01,
|
|
0x29,
|
|
0x0A,
|
|
0x95,
|
|
0x0A,
|
|
0x75,
|
|
0x01,
|
|
0x81,
|
|
0x02,
|
|
};
|
|
constexpr std::array<std::uint8_t, 12> xbox_series_buttons {
|
|
0x05,
|
|
0x09,
|
|
0x19,
|
|
0x01,
|
|
0x29,
|
|
0x0C,
|
|
0x95,
|
|
0x0C,
|
|
0x75,
|
|
0x01,
|
|
0x81,
|
|
0x02,
|
|
};
|
|
constexpr std::array<std::uint8_t, 20> switch_primary_buttons {
|
|
0x05,
|
|
0x09,
|
|
0x19,
|
|
0x01,
|
|
0x29,
|
|
0x0A,
|
|
0x15,
|
|
0x00,
|
|
0x25,
|
|
0x01,
|
|
0x75,
|
|
0x01,
|
|
0x95,
|
|
0x0A,
|
|
0x55,
|
|
0x00,
|
|
0x65,
|
|
0x00,
|
|
0x81,
|
|
0x02,
|
|
};
|
|
constexpr std::array<std::uint8_t, 16> switch_system_buttons {
|
|
0x05,
|
|
0x09,
|
|
0x19,
|
|
0x0B,
|
|
0x29,
|
|
0x0E,
|
|
0x15,
|
|
0x00,
|
|
0x25,
|
|
0x01,
|
|
0x75,
|
|
0x01,
|
|
0x95,
|
|
0x04,
|
|
0x81,
|
|
0x02,
|
|
};
|
|
constexpr std::array<std::uint8_t, 16> switch_compatibility_buttons {
|
|
0x05,
|
|
0x09,
|
|
0x19,
|
|
0x0F,
|
|
0x29,
|
|
0x12,
|
|
0x15,
|
|
0x00,
|
|
0x25,
|
|
0x01,
|
|
0x75,
|
|
0x01,
|
|
0x95,
|
|
0x04,
|
|
0x81,
|
|
0x02,
|
|
};
|
|
|
|
expect_descriptor_contains(xbox_one, xbox_one_buttons);
|
|
expect_descriptor_contains(xbox_series, xbox_series_buttons);
|
|
expect_descriptor_contains(switch_pro, switch_primary_buttons);
|
|
expect_descriptor_contains(switch_pro, switch_system_buttons);
|
|
expect_descriptor_contains(switch_pro, switch_compatibility_buttons);
|
|
}
|
|
|
|
TEST(ProfileTest, NativeControllerPackedButtonsUseExpectedBitSlots) {
|
|
using enum lvh::GamepadButton;
|
|
|
|
const auto xbox_one = lvh::profiles::xbox_one();
|
|
const auto xbox_series = lvh::profiles::xbox_series();
|
|
const auto switch_pro = lvh::profiles::switch_pro();
|
|
|
|
const std::vector<PackedButtonCase> xbox_button_cases {
|
|
{a, 0U},
|
|
{b, 1U},
|
|
{x, 2U},
|
|
{y, 3U},
|
|
{left_shoulder, 4U},
|
|
{right_shoulder, 5U},
|
|
{back, 6U},
|
|
{start, 7U},
|
|
{left_stick, 8U},
|
|
{right_stick, 9U},
|
|
};
|
|
expect_packed_button_bits(xbox_one, xbox_button_cases, 12U);
|
|
expect_packed_button_bits(xbox_series, xbox_button_cases, 12U);
|
|
expect_packed_button_bits(xbox_series, {{misc1, 11U}}, 12U);
|
|
|
|
for (const auto &profile : {xbox_one, xbox_series}) {
|
|
lvh::GamepadState state;
|
|
state.buttons.set(guide);
|
|
const auto report = lvh::reports::pack_input_report(profile, state);
|
|
|
|
ASSERT_GT(report.size(), 15U);
|
|
EXPECT_EQ(read_u16_le(report, 12U), 0U);
|
|
EXPECT_EQ(report[15], 1U);
|
|
}
|
|
|
|
const std::vector<PackedByteButtonCase> switch_button_cases {
|
|
{a, 3U, 0x08U},
|
|
{b, 3U, 0x04U},
|
|
{x, 3U, 0x02U},
|
|
{y, 3U, 0x01U},
|
|
{right_shoulder, 3U, 0x40U},
|
|
{back, 4U, 0x01U},
|
|
{start, 4U, 0x02U},
|
|
{right_stick, 4U, 0x04U},
|
|
{left_stick, 4U, 0x08U},
|
|
{guide, 4U, 0x10U},
|
|
{misc1, 4U, 0x20U},
|
|
{dpad_down, 5U, 0x01U},
|
|
{dpad_up, 5U, 0x02U},
|
|
{dpad_right, 5U, 0x04U},
|
|
{dpad_left, 5U, 0x08U},
|
|
{left_shoulder, 5U, 0x40U},
|
|
};
|
|
for (const auto &[button, offset, mask] : switch_button_cases) {
|
|
lvh::GamepadState state;
|
|
state.buttons.set(button);
|
|
const auto report = lvh::reports::pack_input_report(switch_pro, state);
|
|
|
|
ASSERT_GT(report.size(), offset);
|
|
EXPECT_EQ(report[offset], mask) << "logical button " << static_cast<unsigned>(std::to_underlying(button));
|
|
}
|
|
|
|
lvh::GamepadState trigger_state;
|
|
trigger_state.left_trigger = 1.0F;
|
|
trigger_state.right_trigger = 1.0F;
|
|
const auto trigger_report = lvh::reports::pack_input_report(switch_pro, trigger_state);
|
|
ASSERT_GT(trigger_report.size(), 5U);
|
|
EXPECT_EQ(trigger_report[3], 0x80U);
|
|
EXPECT_EQ(trigger_report[5], 0x80U);
|
|
}
|
|
|
|
TEST(ProfileTest, SwitchProPacksNativeFullControllerState) {
|
|
const auto profile = lvh::profiles::switch_pro();
|
|
lvh::GamepadState state;
|
|
state.left_stick = {.x = 1.0F, .y = 0.0F};
|
|
state.right_stick = {.x = 0.0F, .y = -1.0F};
|
|
|
|
const auto report = lvh::reports::pack_input_report(profile, state);
|
|
ASSERT_EQ(report.size(), 64U);
|
|
EXPECT_EQ(report[0], 0x30U);
|
|
EXPECT_EQ(report[2], 0x81U);
|
|
|
|
// Nintendo packs each stick as two little-endian 12-bit values across three bytes.
|
|
EXPECT_EQ(report[6], 0xFFU);
|
|
EXPECT_EQ(report[7], 0x0FU);
|
|
EXPECT_EQ(report[8], 0x80U);
|
|
EXPECT_EQ(report[9], 0x00U);
|
|
EXPECT_EQ(report[10], 0x08U);
|
|
EXPECT_EQ(report[11], 0x00U);
|
|
|
|
state.battery = lvh::GamepadBattery {.state = lvh::GamepadBatteryState::full, .percentage = 100};
|
|
EXPECT_EQ(lvh::reports::pack_input_report(profile, state)[2], 0x81U);
|
|
state.battery = lvh::GamepadBattery {.state = lvh::GamepadBatteryState::charging, .percentage = 50};
|
|
EXPECT_EQ(lvh::reports::pack_input_report(profile, state)[2], 0x51U);
|
|
}
|
|
|
|
TEST(ProfileTest, RumbleProfilesExposeOutputReports) {
|
|
const auto generic = lvh::profiles::generic_gamepad();
|
|
const auto xbox_360 = lvh::profiles::xbox_360();
|
|
const auto xbox_one = lvh::profiles::xbox_one();
|
|
const auto xbox_series = lvh::profiles::xbox_series();
|
|
|
|
EXPECT_TRUE(generic.capabilities.supports_rumble);
|
|
EXPECT_EQ(generic.output_report_size, 9U);
|
|
constexpr std::array<std::uint8_t, 16> pid_rumble_descriptor {
|
|
0x05,
|
|
0x0F,
|
|
0x09,
|
|
0x97,
|
|
0x15,
|
|
0x00,
|
|
0x25,
|
|
0x01,
|
|
0x75,
|
|
0x04,
|
|
0x95,
|
|
0x01,
|
|
0x91,
|
|
0x02,
|
|
0x15,
|
|
0x00,
|
|
};
|
|
expect_descriptor_contains(generic, pid_rumble_descriptor);
|
|
|
|
EXPECT_TRUE(xbox_360.capabilities.supports_rumble);
|
|
EXPECT_EQ(xbox_360.output_report_size, 5U);
|
|
ASSERT_GE(xbox_360.report_descriptor.size(), 3U);
|
|
EXPECT_EQ(xbox_360.report_descriptor[xbox_360.report_descriptor.size() - 3U], 0x91);
|
|
EXPECT_EQ(xbox_360.report_descriptor[xbox_360.report_descriptor.size() - 2U], 0x02);
|
|
EXPECT_EQ(xbox_360.report_descriptor.back(), 0xC0);
|
|
|
|
EXPECT_EQ(xbox_one.output_report_size, 8U);
|
|
EXPECT_EQ(xbox_series.output_report_size, 8U);
|
|
expect_descriptor_contains(xbox_one, pid_rumble_descriptor);
|
|
expect_descriptor_contains(xbox_series, pid_rumble_descriptor);
|
|
}
|
|
|
|
TEST(ProfileTest, CanFindProfileByKind) {
|
|
const auto profile = lvh::profiles::gamepad_profile(lvh::GamepadProfileKind::xbox_series);
|
|
|
|
ASSERT_TRUE(profile.has_value());
|
|
EXPECT_EQ(profile->gamepad_kind, lvh::GamepadProfileKind::xbox_series);
|
|
}
|
|
|
|
TEST(ProfileTest, PointerProfilesArePresent) {
|
|
const auto keyboard = lvh::profiles::keyboard();
|
|
const auto mouse = lvh::profiles::mouse();
|
|
const auto touchscreen = lvh::profiles::touchscreen();
|
|
const auto trackpad = lvh::profiles::trackpad();
|
|
const auto pen_tablet = lvh::profiles::pen_tablet();
|
|
|
|
EXPECT_EQ(keyboard.device_type, lvh::DeviceType::keyboard);
|
|
EXPECT_FALSE(keyboard.name.empty());
|
|
EXPECT_NE(keyboard.vendor_id, 0);
|
|
EXPECT_NE(keyboard.product_id, 0);
|
|
|
|
EXPECT_EQ(mouse.device_type, lvh::DeviceType::mouse);
|
|
EXPECT_FALSE(mouse.name.empty());
|
|
EXPECT_NE(mouse.vendor_id, 0);
|
|
EXPECT_NE(mouse.product_id, 0);
|
|
|
|
EXPECT_EQ(touchscreen.device_type, lvh::DeviceType::touchscreen);
|
|
EXPECT_FALSE(touchscreen.name.empty());
|
|
EXPECT_NE(touchscreen.product_id, 0);
|
|
|
|
EXPECT_EQ(trackpad.device_type, lvh::DeviceType::trackpad);
|
|
EXPECT_FALSE(trackpad.name.empty());
|
|
EXPECT_NE(trackpad.product_id, 0);
|
|
|
|
EXPECT_EQ(pen_tablet.device_type, lvh::DeviceType::pen_tablet);
|
|
EXPECT_FALSE(pen_tablet.name.empty());
|
|
EXPECT_NE(pen_tablet.product_id, 0);
|
|
}
|