blob: 78b165e9615fed6184923fa2ba18f47337422ceb [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 "src/ui/input/lib/hid-input-report/sensor.h"
#include <lib/fit/defer.h>
#include <lib/hid-parser/usages.h>
#include <lib/hid/ambient-light.h>
#include <lib/hid/multi-sensor.h>
#include <variant>
#include <zxtest/zxtest.h>
#include "src/ui/input/lib/hid-input-report/device.h"
#include "src/ui/input/lib/hid-input-report/test/test.h"
// Each test parses the report descriptor for the mouse and then sends one
// report to ensure that it has been parsed correctly.
namespace hid_input_report {
TEST(SensorTest, AmbientLight) {
// Create the descriptor.
hid::DeviceDescriptor* dev_desc = nullptr;
const uint8_t* desc;
size_t desc_size = get_ambient_light_report_desc(&desc);
hid::ParseResult parse_res = hid::ParseReportDescriptor(desc, desc_size, &dev_desc);
ASSERT_EQ(hid::ParseResult::kParseOk, parse_res);
auto free_descriptor = fit::defer([dev_desc]() { hid::FreeDeviceDescriptor(dev_desc); });
hid_input_report::Sensor sensor;
// Parse the descriptor.
EXPECT_EQ(hid_input_report::ParseResult::kOk, sensor.ParseReportDescriptor(dev_desc->report[1]));
hid_input_report::TestDescriptorAllocator descriptor_allocator;
fuchsia_input_report::wire::DeviceDescriptor descriptor(descriptor_allocator);
fuchsia_input_report::wire::SensorDescriptor sensor_desc(descriptor_allocator);
fidl::VectorView<fuchsia_input_report::wire::SensorInputDescriptor> input(descriptor_allocator,
1);
sensor_desc.set_input(descriptor_allocator, std::move(input));
descriptor.set_sensor(descriptor_allocator, std::move(sensor_desc));
EXPECT_EQ(hid_input_report::ParseResult::kOk,
sensor.CreateDescriptor(descriptor_allocator, descriptor));
EXPECT_TRUE(descriptor.has_sensor());
EXPECT_TRUE(descriptor.sensor().has_input());
// Check the descriptor.
ASSERT_EQ(1, descriptor.sensor().input().count());
ASSERT_EQ(4, descriptor.sensor().input()[0].values().count());
ASSERT_EQ(descriptor.sensor().input()[0].values()[0].type,
fuchsia_input_report::wire::SensorType::kLightIlluminance);
ASSERT_EQ(descriptor.sensor().input()[0].values()[0].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
ASSERT_EQ(descriptor.sensor().input()[0].values()[1].type,
fuchsia_input_report::wire::SensorType::kLightRed);
ASSERT_EQ(descriptor.sensor().input()[0].values()[1].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
ASSERT_EQ(descriptor.sensor().input()[0].values()[2].type,
fuchsia_input_report::wire::SensorType::kLightBlue);
ASSERT_EQ(descriptor.sensor().input()[0].values()[2].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
ASSERT_EQ(descriptor.sensor().input()[0].values()[3].type,
fuchsia_input_report::wire::SensorType::kLightGreen);
ASSERT_EQ(descriptor.sensor().input()[0].values()[3].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
// Create the report.
ambient_light_input_rpt_t report_data = {};
// Values are arbitrarily chosen.
constexpr int kIlluminanceTestVal = 10;
constexpr int kRedTestVal = 101;
constexpr int kBlueTestVal = 5;
constexpr int kGreenTestVal = 3;
report_data.rpt_id = AMBIENT_LIGHT_RPT_ID_INPUT;
report_data.illuminance = kIlluminanceTestVal;
report_data.red = kRedTestVal;
report_data.blue = kBlueTestVal;
report_data.green = kGreenTestVal;
// Parse the report.
hid_input_report::TestReportAllocator report_allocator;
fuchsia_input_report::wire::InputReport input_report(report_allocator);
EXPECT_EQ(hid_input_report::ParseResult::kOk,
sensor.ParseInputReport(reinterpret_cast<uint8_t*>(&report_data), sizeof(report_data),
report_allocator, input_report));
ASSERT_TRUE(input_report.has_sensor());
EXPECT_EQ(4, input_report.sensor().values().count());
// Check the report.
// These will always match the ordering in the descriptor.
EXPECT_EQ(kIlluminanceTestVal, input_report.sensor().values()[0]);
EXPECT_EQ(kRedTestVal, input_report.sensor().values()[1]);
EXPECT_EQ(kBlueTestVal, input_report.sensor().values()[2]);
EXPECT_EQ(kGreenTestVal, input_report.sensor().values()[3]);
}
TEST(SensorTest, DeviceType) {
Sensor device;
ASSERT_EQ(DeviceType::kSensor, device.GetDeviceType());
}
TEST(SensorTest, MultiSensor) {
// Create the descriptor.
hid::DeviceDescriptor* dev_desc = nullptr;
const uint8_t* desc;
size_t desc_size = get_multi_sensor_report_desc(&desc);
ASSERT_NOT_NULL(desc);
hid::ParseResult parse_res = hid::ParseReportDescriptor(desc, desc_size, &dev_desc);
ASSERT_NOT_NULL(dev_desc);
ASSERT_EQ(hid::ParseResult::kParseOk, parse_res);
auto free_descriptor = fit::defer([dev_desc]() { hid::FreeDeviceDescriptor(dev_desc); });
ASSERT_EQ(5, dev_desc->rep_count);
hid_input_report::TestDescriptorAllocator descriptor_allocator;
fuchsia_input_report::wire::DeviceDescriptor descriptor(descriptor_allocator);
fuchsia_input_report::wire::SensorDescriptor sensor_desc(descriptor_allocator);
fidl::VectorView<fuchsia_input_report::wire::SensorInputDescriptor> input(descriptor_allocator,
5);
sensor_desc.set_input(descriptor_allocator, std::move(input));
descriptor.set_sensor(descriptor_allocator, std::move(sensor_desc));
std::array<hid_input_report::Sensor, 5> sensor;
for (uint32_t i = 0; i < std::size(sensor); i++) {
// Parse the descriptor.
EXPECT_EQ(hid_input_report::ParseResult::kOk,
sensor[i].ParseReportDescriptor(dev_desc->report[i]));
EXPECT_EQ(hid_input_report::ParseResult::kOk,
sensor[i].CreateDescriptor(descriptor_allocator, descriptor));
ASSERT_TRUE(descriptor.has_sensor());
EXPECT_TRUE(descriptor.sensor().has_input());
}
ASSERT_EQ(std::size(sensor), descriptor.sensor().input().count());
// Accelerometer
{
ASSERT_TRUE(descriptor.sensor().input()[0].has_report_id());
EXPECT_EQ(ACCELEROMETER_RPT_ID_B, descriptor.sensor().input()[0].report_id());
ASSERT_TRUE(descriptor.sensor().input()[0].has_values());
ASSERT_EQ(3, descriptor.sensor().input()[0].values().count());
EXPECT_EQ(descriptor.sensor().input()[0].values()[0].type,
fuchsia_input_report::wire::SensorType::kAccelerometerX);
EXPECT_EQ(descriptor.sensor().input()[0].values()[0].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
EXPECT_EQ(descriptor.sensor().input()[0].values()[1].type,
fuchsia_input_report::wire::SensorType::kAccelerometerY);
EXPECT_EQ(descriptor.sensor().input()[0].values()[1].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
EXPECT_EQ(descriptor.sensor().input()[0].values()[2].type,
fuchsia_input_report::wire::SensorType::kAccelerometerZ);
EXPECT_EQ(descriptor.sensor().input()[0].values()[2].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
// Create the report.
accelerometer_input_rpt_t report_data = {};
// Values are arbitrarily chosen.
constexpr int kAccelerometerXTestVal = 10;
constexpr int kAccelerometerYTestVal = 20;
constexpr int kAccelerometerZTestVal = 30;
report_data.rpt_id = ACCELEROMETER_RPT_ID_B;
report_data.x = kAccelerometerXTestVal;
report_data.y = kAccelerometerYTestVal;
report_data.z = kAccelerometerZTestVal;
// Parse the report.
hid_input_report::TestReportAllocator report_allocator;
fuchsia_input_report::wire::InputReport input_report(report_allocator);
EXPECT_EQ(hid_input_report::ParseResult::kOk,
sensor[0].ParseInputReport(reinterpret_cast<uint8_t*>(&report_data),
sizeof(report_data), report_allocator, input_report));
ASSERT_TRUE(input_report.has_sensor());
ASSERT_EQ(3, input_report.sensor().values().count());
// Check the report.
// These will always match the ordering in the descriptor.
EXPECT_EQ(kAccelerometerXTestVal, input_report.sensor().values()[0]);
EXPECT_EQ(kAccelerometerYTestVal, input_report.sensor().values()[1]);
EXPECT_EQ(kAccelerometerZTestVal, input_report.sensor().values()[2]);
}
// Gyrometer
{
ASSERT_TRUE(descriptor.sensor().input()[1].has_report_id());
EXPECT_EQ(GYROMETER_RPT_ID, descriptor.sensor().input()[1].report_id());
ASSERT_TRUE(descriptor.sensor().input()[1].has_values());
ASSERT_EQ(3, descriptor.sensor().input()[1].values().count());
EXPECT_EQ(descriptor.sensor().input()[1].values()[0].type,
fuchsia_input_report::wire::SensorType::kGyroscopeX);
EXPECT_EQ(descriptor.sensor().input()[1].values()[0].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
EXPECT_EQ(descriptor.sensor().input()[1].values()[1].type,
fuchsia_input_report::wire::SensorType::kGyroscopeY);
EXPECT_EQ(descriptor.sensor().input()[1].values()[1].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
EXPECT_EQ(descriptor.sensor().input()[1].values()[2].type,
fuchsia_input_report::wire::SensorType::kGyroscopeZ);
EXPECT_EQ(descriptor.sensor().input()[1].values()[2].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
// Create the report.
gyrometer_input_rpt_t gyrometer_report_data = {};
// Values are arbitrarily chosen.
constexpr int kGyroscopeXTestVal = 12;
constexpr int kGyroscopeYTestVal = 15;
constexpr int kGyroscopeZTestVal = 18;
gyrometer_report_data.rpt_id = GYROMETER_RPT_ID;
gyrometer_report_data.x = kGyroscopeXTestVal;
gyrometer_report_data.y = kGyroscopeYTestVal;
gyrometer_report_data.z = kGyroscopeZTestVal;
// Parse the report.
hid_input_report::TestReportAllocator report_allocator;
fuchsia_input_report::wire::InputReport input_report(report_allocator);
EXPECT_EQ(
hid_input_report::ParseResult::kOk,
sensor[1].ParseInputReport(reinterpret_cast<uint8_t*>(&gyrometer_report_data),
sizeof(gyrometer_report_data), report_allocator, input_report));
ASSERT_TRUE(input_report.has_sensor());
ASSERT_EQ(3, input_report.sensor().values().count());
// Check the report.
// These will always match the ordering in the descriptor.
EXPECT_EQ(kGyroscopeXTestVal, input_report.sensor().values()[0]);
EXPECT_EQ(kGyroscopeYTestVal, input_report.sensor().values()[1]);
EXPECT_EQ(kGyroscopeZTestVal, input_report.sensor().values()[2]);
}
// Compass
{
ASSERT_TRUE(descriptor.sensor().input()[2].has_report_id());
EXPECT_EQ(COMPASS_RPT_ID, descriptor.sensor().input()[2].report_id());
ASSERT_TRUE(descriptor.sensor().input()[2].has_values());
ASSERT_EQ(3, descriptor.sensor().input()[2].values().count());
EXPECT_EQ(descriptor.sensor().input()[2].values()[0].type,
fuchsia_input_report::wire::SensorType::kMagnetometerX);
EXPECT_EQ(descriptor.sensor().input()[2].values()[0].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
EXPECT_EQ(descriptor.sensor().input()[2].values()[1].type,
fuchsia_input_report::wire::SensorType::kMagnetometerY);
EXPECT_EQ(descriptor.sensor().input()[2].values()[1].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
EXPECT_EQ(descriptor.sensor().input()[2].values()[2].type,
fuchsia_input_report::wire::SensorType::kMagnetometerZ);
EXPECT_EQ(descriptor.sensor().input()[2].values()[2].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
// Create the report.
compass_input_rpt_t compass_report_data = {};
// Values are arbitrarily chosen.
constexpr int kCompassXTestVal = 15;
constexpr int kCompassYTestVal = 10;
constexpr int kCompassZTestVal = 5;
compass_report_data.rpt_id = COMPASS_RPT_ID;
compass_report_data.x = kCompassXTestVal;
compass_report_data.y = kCompassYTestVal;
compass_report_data.z = kCompassZTestVal;
// Parse the report.
hid_input_report::TestReportAllocator report_allocator;
fuchsia_input_report::wire::InputReport input_report(report_allocator);
EXPECT_EQ(
hid_input_report::ParseResult::kOk,
sensor[2].ParseInputReport(reinterpret_cast<uint8_t*>(&compass_report_data),
sizeof(compass_report_data), report_allocator, input_report));
ASSERT_TRUE(input_report.has_sensor());
ASSERT_EQ(3, input_report.sensor().values().count());
// Check the report.
// These will always match the ordering in the descriptor.
EXPECT_EQ(kCompassXTestVal, input_report.sensor().values()[0]);
EXPECT_EQ(kCompassYTestVal, input_report.sensor().values()[1]);
EXPECT_EQ(kCompassZTestVal, input_report.sensor().values()[2]);
}
// Accelerometer_B
{
ASSERT_TRUE(descriptor.sensor().input()[3].has_report_id());
EXPECT_EQ(ACCELEROMETER_RPT_ID_A, descriptor.sensor().input()[3].report_id());
ASSERT_TRUE(descriptor.sensor().input()[3].has_values());
ASSERT_EQ(3, descriptor.sensor().input()[3].values().count());
EXPECT_EQ(descriptor.sensor().input()[3].values()[0].type,
fuchsia_input_report::wire::SensorType::kAccelerometerX);
EXPECT_EQ(descriptor.sensor().input()[3].values()[0].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
EXPECT_EQ(descriptor.sensor().input()[3].values()[1].type,
fuchsia_input_report::wire::SensorType::kAccelerometerY);
EXPECT_EQ(descriptor.sensor().input()[3].values()[1].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
EXPECT_EQ(descriptor.sensor().input()[3].values()[2].type,
fuchsia_input_report::wire::SensorType::kAccelerometerZ);
EXPECT_EQ(descriptor.sensor().input()[3].values()[2].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
// Create the report.
accelerometer_input_rpt_t accelerometer_report_data = {};
// Values are arbitrarily chosen.
constexpr int kAccelerometerXTestVal = 30;
constexpr int kAccelerometerYTestVal = 35;
constexpr int kAccelerometerZTestVal = 20;
accelerometer_report_data.rpt_id = ACCELEROMETER_RPT_ID_A;
accelerometer_report_data.x = kAccelerometerXTestVal;
accelerometer_report_data.y = kAccelerometerYTestVal;
accelerometer_report_data.z = kAccelerometerZTestVal;
// Parse the report.
hid_input_report::TestReportAllocator report_allocator;
fuchsia_input_report::wire::InputReport input_report(report_allocator);
EXPECT_EQ(hid_input_report::ParseResult::kOk,
sensor[3].ParseInputReport(reinterpret_cast<uint8_t*>(&accelerometer_report_data),
sizeof(accelerometer_report_data), report_allocator,
input_report));
ASSERT_TRUE(input_report.has_sensor());
ASSERT_EQ(3, input_report.sensor().values().count());
// Check the report.
// These will always match the ordering in the descriptor.
EXPECT_EQ(kAccelerometerXTestVal, input_report.sensor().values()[0]);
EXPECT_EQ(kAccelerometerYTestVal, input_report.sensor().values()[1]);
EXPECT_EQ(kAccelerometerZTestVal, input_report.sensor().values()[2]);
}
// Ambient Light
{
ASSERT_TRUE(descriptor.sensor().input()[4].has_report_id());
EXPECT_EQ(ILLUMINANCE_RPT_ID, descriptor.sensor().input()[4].report_id());
ASSERT_TRUE(descriptor.sensor().input()[4].has_values());
ASSERT_EQ(1, descriptor.sensor().input()[4].values().count());
EXPECT_EQ(descriptor.sensor().input()[4].values()[0].type,
fuchsia_input_report::wire::SensorType::kLightIlluminance);
EXPECT_EQ(descriptor.sensor().input()[4].values()[0].axis.unit.type,
fuchsia_input_report::wire::UnitType::kNone);
// Create the report.
illuminance_input_rpt_t illuminance_report_data = {};
// Values are arbitrarily chosen.
constexpr int kIlluminanceTestVal = 343;
illuminance_report_data.rpt_id = ILLUMINANCE_RPT_ID;
illuminance_report_data.illuminance = kIlluminanceTestVal;
// Parse the report.
hid_input_report::TestReportAllocator report_allocator;
fuchsia_input_report::wire::InputReport input_report(report_allocator);
EXPECT_EQ(hid_input_report::ParseResult::kOk,
sensor[4].ParseInputReport(reinterpret_cast<uint8_t*>(&illuminance_report_data),
sizeof(illuminance_report_data), report_allocator,
input_report));
ASSERT_TRUE(input_report.has_sensor());
ASSERT_EQ(1, input_report.sensor().values().count());
// Check the report.
// These will always match the ordering in the descriptor.
EXPECT_EQ(kIlluminanceTestVal, input_report.sensor().values()[0]);
}
}
} // namespace hid_input_report