TestIOHIDEventDriver_DeviceOrientationTilt.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 "IOHIDDeviceOrientationTiltDescriptor.h"

@interface TestIOHIDEventDriver_DeviceOrientationTilt : IOHIDEventDriverTestCase

@property XCTestExpectation * testEventExpectation;
@property XCTestExpectation * testReportExpectation;
@property XCTestExpectation * testCopyEventExpectation;

@end

@implementation TestIOHIDEventDriver_DeviceOrientationTilt

- (void)setUp {

self.testEventExpectation = [[XCTestExpectation alloc] initWithDescription:@"Expectation: event"];
self.testCopyEventExpectation = [[XCTestExpectation alloc] initWithDescription:@"Expectation: copy event"];
self.testReportExpectation = [[XCTestExpectation alloc] initWithDescription:@"Expectation: report"];
self.testEventExpectation.expectedFulfillmentCount = 3;

static uint8_t descriptor [] = {
HIDDisplayOrientationTilt
};

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

[super setUp];
}

- (void)tearDown {

[super tearDown];
}

- (void)testDeviceOrientationTiltEvent {
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 %@",
(long)result,
self.testServiceExpectation);

HIDDisplayOrientationTiltInputReport01 report;

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

report.reportId = 1;
report.SNS_OrientationDeviceOrientationDataFieldTiltXAxis = 180;
report.SNS_OrientationDeviceOrientationDataFieldTiltYAxis = 90;
report.SNS_OrientationDeviceOrientationDataFieldTiltZAxis = 270;

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);

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.SNS_OrientationDeviceOrientationDataFieldTiltXAxis = 0;
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.SNS_OrientationDeviceOrientationDataFieldTiltXAxis = 90;
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 x;
IOHIDFloat y;
IOHIDFloat z;

x = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[0], kIOHIDEventFieldOrientationTiltX);
y = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[0], kIOHIDEventFieldOrientationTiltY);
z = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[0], kIOHIDEventFieldOrientationTiltZ);
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
x == 180.0 && y == 90.0 && z == 270.0,
"x:%f y:%f z:%f events:%@",
x,
y,
z,
self.events);

x = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[1], kIOHIDEventFieldOrientationTiltX);
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
x == 0.0,
"x:%f events:%@",
x,
self.events);

x = IOHIDEventGetFloatValue((IOHIDEventRef)self.events[2], kIOHIDEventFieldOrientationTiltX);
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
x == 90.0,
"x:%f events:%@",
x,
self.events);

__block IOHIDEventRef copyEvent;
dispatch_async (dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
copyEvent = IOHIDServiceClientCopyEvent(self.eventService, kIOHIDEventTypeOrientation, NULL, 0);
[self.testCopyEventExpectation fulfill];
});

result = [XCTWaiter waitForExpectations:@[self.testCopyEventExpectation] timeout:10];
HIDXCTAssertWithParameters ( RETURN_FROM_TEST | COLLECT_ALL,
result == XCTWaiterResultCompleted && copyEvent != NULL,
"result:%ld copyEvent:%@ expectation:%@",
(long)result,
copyEvent,
self.testCopyEventExpectation);

CFIndex value = IOHIDEventGetIntegerValue (copyEvent, kIOHIDEventFieldOrientationOrientationType);
XCTAssert (value == kIOHIDOrientationTypeTilt);

x = IOHIDEventGetFloatValue((IOHIDEventRef)copyEvent, kIOHIDEventFieldOrientationTiltX);
y = IOHIDEventGetFloatValue((IOHIDEventRef)copyEvent, kIOHIDEventFieldOrientationTiltY);
z = IOHIDEventGetFloatValue((IOHIDEventRef)copyEvent, kIOHIDEventFieldOrientationTiltZ);
HIDXCTAssertWithParameters (RETURN_FROM_TEST,
x == 90.0 && y == 180.0 && z == 0.0,
"x:%f y:%f z:%f copyEvent:%@",
x,
y,
z,
copyEvent);
if (copyEvent) {
CFRelease(copyEvent);
}
}

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

[super handleEvent:event fromService:service];

if (IOHIDEventGetType(event) == kIOHIDEventTypeOrientation && IOHIDEventGetIntegerValue(event, kIOHIDEventFieldOrientationOrientationType) == kIOHIDOrientationTypeTilt) {
[self.testEventExpectation fulfill];
}
}

-(IOReturn)userDeviceGetReportHandler: (IOHIDReportType)type :(uint32_t)reportID :(uint8_t *)report :(NSUInteger *) length
{
NSLog(@"userDeviceGetReportHandler:%d :%d :%p :%lu", type, reportID, report, (unsigned long)*length);

if (*length < sizeof (HIDDisplayOrientationTiltInputReport01) || reportID != 1 || type != kIOHIDReportTypeInput) {

return kIOReturnUnsupported;
}

HIDDisplayOrientationTiltInputReport01 * reportData = (HIDDisplayOrientationTiltInputReport01 *) report;
reportData->reportId = (uint8_t) reportID;
reportData->SNS_OrientationDeviceOrientationDataFieldTiltXAxis = 90;
reportData->SNS_OrientationDeviceOrientationDataFieldTiltYAxis = 180;
reportData->SNS_OrientationDeviceOrientationDataFieldTiltZAxis = 0;

[self.testReportExpectation fulfill];

return kIOReturnSuccess;
}

@end