TestIOHIDEventDriver_Gyro.m   [plain text]

//
// TestIOHIDEventDriver_Gyro.m
// IOHIDFamilyUnitTests
//
// Created by yg on 8/13/18.
//

#import <XCTest/XCTest.h>
#include "IOHIDUnitTestUtility.h"
#import "IOHIDEventDriverTestCase.h"
#import "IOHIDGyroDescriptor.h"

@interface TestIOHIDEventDriver_Gyro : IOHIDEventDriverTestCase

@property XCTestExpectation * testEventExpectation;

@end

@implementation TestIOHIDEventDriver_Gyro

- (void)setUp {

self.testEventExpectation = [[XCTestExpectation alloc] initWithDescription:@"Expectation: Gyro event"];
self.testEventExpectation.expectedFulfillmentCount = 6;

static uint8_t descriptor [] = {
HIDGyro
};

self.hidDeviceDescriptor = [NSData dataWithBytes:descriptor length:sizeof(descriptor)];

[super setUp];
}

- (void)tearDown {

[super tearDown];
}

- (void)testGyroEvent {
IOReturn status;

XCTWaiterResult result;

HIDXCTAssertWithParameters (RETURN_FROM_TEST | COLLECT_LOGARCHIVE, self.eventSystem != NULL);

HIDXCTAssertWithParameters (RETURN_FROM_TEST | COLLECT_LOGARCHIVE, self.userDevice != NULL, "User device description: %@", self.userDeviceDescription);

result = [XCTWaiter waitForExpectations:@[self.testServiceExpectation] timeout:10];
HIDXCTAssertWithParameters ( RETURN_FROM_TEST | COLLECT_TAILSPIN | COLLECT_IOREG,
result == XCTWaiterResultCompleted,
"result:%ld %@",
result,
self.testServiceExpectation);

HIDGyroInputReport01 report;

memset(&report, 0, sizeof(report));

report.reportId = 1;
report.SNS_MotionGyrometerDataFieldAngularVelocityAboutXAxis = 1000;
report.SNS_MotionGyrometerDataFieldAngularVelocityAboutYAxis = 1000;
report.SNS_MotionGyrometerDataFieldAngularVelocityAboutZAxis = 1000;

report.MotionGyrometer000B = 1;
status = IOHIDUserDeviceHandleReport(self.userDevice, (uint8_t *)&report, sizeof(report));
HIDXCTAssertWithParameters ( RETURN_FROM_TEST | COLLECT_HIDUTIL | COLLECT_IOREG | COLLECT_LOGARCHIVE,
status == kIOReturnSuccess,
"IOHIDUserDeviceHandleReport:0x%x",
status);

report.MotionGyrometer000B = 2;
status = IOHIDUserDeviceHandleReport(self.userDevice, (uint8_t *)&report, sizeof(report));
HIDXCTAssertWithParameters ( RETURN_FROM_TEST | COLLECT_HIDUTIL | COLLECT_IOREG | COLLECT_LOGARCHIVE,
status == kIOReturnSuccess,
"IOHIDUserDeviceHandleReport:0x%x",
status);

report.MotionGyrometer000B = 3;
report.SNS_MotionGyrometerDataFieldAngularVelocityAboutZAxis = 2000;
status = IOHIDUserDeviceHandleReport(self.userDevice, (uint8_t *)&report, sizeof(report));
HIDXCTAssertWithParameters ( RETURN_FROM_TEST | COLLECT_HIDUTIL | COLLECT_IOREG | COLLECT_LOGARCHIVE,
status == kIOReturnSuccess,
"IOHIDUserDeviceHandleReport:0x%x",
status);

report.MotionGyrometer000B = 4;
report.MotionGyrometer0009 = kIOHIDMotionTypeShake;
report.SNS_MotionGyrometerDataFieldAngularVelocityAboutZAxis = -1000;
status = IOHIDUserDeviceHandleReport(self.userDevice, (uint8_t *)&report, sizeof(report));
HIDXCTAssertWithParameters ( RETURN_FROM_TEST | COLLECT_HIDUTIL | COLLECT_IOREG | COLLECT_LOGARCHIVE,
status == kIOReturnSuccess,
"IOHIDUserDeviceHandleReport:0x%x",
status);

report.MotionGyrometer000B = 5;
report.MotionGyrometer0009 = kIOHIDMotionTypePath;
report.SNS_MotionGyrometerDataFieldAngularVelocityAboutZAxis = -1000;
status = IOHIDUserDeviceHandleReport(self.userDevice, (uint8_t *)&report, sizeof(report));
HIDXCTAssertWithParameters ( RETURN_FROM_TEST | COLLECT_HIDUTIL | COLLECT_IOREG | COLLECT_LOGARCHIVE,
status == kIOReturnSuccess,
"IOHIDUserDeviceHandleReport:0x%x",
status);

report.MotionGyrometer000B = 6;
report.MotionGyrometer0009 = kIOHIDMotionTypePath;
report.MotionGyrometer000A = kIOHIDMotionPathEnd;
report.SNS_MotionGyrometerDataFieldAngularVelocityAboutZAxis = -1000;
status = IOHIDUserDeviceHandleReport(self.userDevice, (uint8_t *)&report, sizeof(report));
HIDXCTAssertWithParameters ( RETURN_FROM_TEST | COLLECT_HIDUTIL | COLLECT_IOREG | COLLECT_LOGARCHIVE,
status == kIOReturnSuccess,
"IOHIDUserDeviceHandleReport:0x%x",
status);

result = [XCTWaiter waitForExpectations:@[self.testEventExpectation] timeout:10];
HIDXCTAssertWithParameters ( RETURN_FROM_TEST | COLLECT_ALL,
result == XCTWaiterResultCompleted,
"result:%ld %@",
(long)result,
self.testEventExpectation);

IOHIDFloat value0;
IOHIDFloat value1;

value0 = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[0], kIOHIDEventFieldGyroX);
value1 = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[1], kIOHIDEventFieldGyroX);
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
value0 == value1 && value0 != 0,
"events:%@",
self.events);

value0 = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[0], kIOHIDEventFieldGyroY);
value1 = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[1], kIOHIDEventFieldGyroY);
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
value0 == value1 && value0 != 0,
"events:%@",
self.events);

value0 = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[0], kIOHIDEventFieldGyroZ);
value1 = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[1], kIOHIDEventFieldGyroZ);
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
value0 == value1 && value0 != 0,
"events:%@",
self.events);

value0 = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[2], kIOHIDEventFieldGyroZ);
value1 = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[3], kIOHIDEventFieldGyroZ);
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
value0 != value1 && value1 < 0,
"events:%@",
self.events);

for (NSUInteger index = 0; index < self.events.count; index++) {
NSUInteger sequence = IOHIDEventGetIntegerValue((IOHIDEventRef)self.events[index], kIOHIDEventFieldGyroSequence);
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
sequence == index + 1,
"index:%ld events:%@",
(long)index,
self.events);

NSInteger expectedType;
NSInteger type = IOHIDEventGetIntegerValue((IOHIDEventRef)self.events[index], kIOHIDEventFieldGyroType);
if (index < 3) {
expectedType = 0;
} else if (index < 4) {
expectedType = kIOHIDMotionTypeShake;
} else {
expectedType = kIOHIDMotionTypePath;
}
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
type == expectedType,
"type:%ld (%ld) index:%ld events:%@",
(long)type,
(long)expectedType,
(long)index,
self.events);

NSInteger expectedSubType;
NSInteger subType = IOHIDEventGetIntegerValue((IOHIDEventRef)self.events[index], kIOHIDEventFieldGyroSubType);
if (index < 5) {
expectedSubType = 0;
} else {
expectedSubType = 1;
}
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
subType == expectedSubType,
"index:%ld events:%@",
(long)index,
self.events);
}

}

-(void) handleEvent: (IOHIDEventRef) event fromService:(IOHIDServiceClientRef __unused) service
{

[super handleEvent:event fromService:service];

if (IOHIDEventGetType(event) == kIOHIDEventTypeGyro) {
[self.testEventExpectation fulfill];
}
}

@end