TestServiceTerminationEvents.m [plain text]
//
// TestServiceTerminationEvents.m
// IOHIDFamily
//
// Created by YG on 10/25/16.
//
//
#import <XCTest/XCTest.h>
#include "IOHIDUnitTestUtility.h"
#include "IOHIDXCTestExpectation.h"
#import "IOHIDUnitTestDescriptors.h"
#include <IOKit/hid/IOHIDUserDevice.h>
#include <IOKit/hid/IOHIDEventSystemClient.h>
#define fulfill(exp) \
exp.expectationDescription = [exp.expectationDescription stringByAppendingString:@"(fullfilled)"];\
[exp fulfill];
static uint8_t descriptor[] = {
HIDKeyboardDescriptor
};
@interface TestServiceTerminationEvents : XCTestCase
@property IOHIDEventSystemClientRef eventSystem;
@property IOHIDUserDeviceRef userDevice;
@property IOHIDXCTestExpectation * testServiceExpectation;
@property IOHIDXCTestExpectation * testKbcDownEventExpectation;
@property IOHIDXCTestExpectation * testKbcUpEventExpectation;
@property IOHIDXCTestExpectation * testNullEventExpectation;
@property NSMutableArray * events;
@end
@implementation TestServiceTerminationEvents
- (void)setUp {
[super setUp];
self.events = [[NSMutableArray alloc] init];
NSString * uniqueID = [[[NSUUID alloc] init] UUIDString];
self.eventSystem = IOHIDEventSystemClientCreateWithType (kCFAllocatorDefault, kIOHIDEventSystemClientTypeMonitor, NULL);
HIDXCTAssertAndThrowTrue(self.eventSystem != NULL);
NSDictionary *matching = @{@kIOHIDPhysicalDeviceUniqueIDKey : uniqueID};
IOHIDEventSystemClientSetMatching(self.eventSystem , (__bridge CFDictionaryRef)matching);
self.testServiceExpectation = [[IOHIDXCTestExpectation alloc] initWithDescription:@"expectation: Test HID service"];
self.testKbcDownEventExpectation = [[IOHIDXCTestExpectation alloc] initWithDescription:@"expectation: keyboard event down"];
self.testKbcUpEventExpectation = [[IOHIDXCTestExpectation alloc] initWithDescription:@"expectation: Keyboard event Up"];
self.testNullEventExpectation = [[IOHIDXCTestExpectation alloc] initWithDescription:@"expectation: Null event"];
IOHIDServiceClientBlock handler = ^(void * _Nullable target __unused, void * _Nullable refcon __unused, IOHIDServiceClientRef _Nonnull service __unused) {
[self.testServiceExpectation fulfill];
};
IOHIDEventSystemClientRegisterDeviceMatchingBlock(self.eventSystem , handler, NULL, NULL);
IOHIDEventSystemClientRegisterEventBlock(self.eventSystem, ^(void * _Nullable target __unused, void * _Nullable refcon __unused, void * _Nullable sender __unused, IOHIDEventRef _Nonnull event) {
NSLog(@"Event: if (IOHIDEventGetType(event) == kIOHIDEventTypeKeyboard && IOHIDEventGetIntegerValue(event, kIOHIDEventFieldKeyboardUsage) == kHIDUsage_KeypadEqualSignAS400) {
if (IOHIDEventGetIntegerValue(event, kIOHIDEventFieldKeyboardDown)) {
[self.testKbcDownEventExpectation fulfill];
} else {
[self.testKbcUpEventExpectation fulfill];
}
} else if (IOHIDEventGetType(event) == kIOHIDEventTypeNULL) {
[self.testNullEventExpectation fulfill];
} else {
[self.events addObject: (__bridge id _Nonnull)event];
}
}, NULL, NULL);
IOHIDEventSystemClientScheduleWithDispatchQueue(self.eventSystem, dispatch_get_main_queue());
NSDictionary * description = @{
@kIOHIDPhysicalDeviceUniqueIDKey : uniqueID,
@kIOHIDReportDescriptorKey : [NSData dataWithBytes:descriptor length:sizeof(descriptor)],
@kIOHIDVendorIDKey : @(555),
@kIOHIDProductIDKey : @(555),
};
self.userDevice = IOHIDUserDeviceCreate(kCFAllocatorDefault, (CFDictionaryRef)description);
HIDXCTAssertAndThrowTrue(self.userDevice != NULL, "HID User Device config:
}
- (void)tearDown {
if (self.userDevice) {
CFRelease(self.userDevice);
}
if (self.eventSystem) {
CFRelease(self.eventSystem);
}
[super tearDown];
}
- (void)testKeyboardServiceTerminationEvent {
XCTWaiterResult result;
IOReturn status;
result = [XCTWaiter waitForExpectations:@[self.testServiceExpectation] timeout:10];
XCTAssert(result == XCTWaiterResultCompleted, "result:
HIDKeyboardDescriptorInputReport report;
memset(&report, 0, sizeof(report));
report.KB_Keyboard[0] = kHIDUsage_KeypadEqualSignAS400;
status = IOHIDUserDeviceHandleReport(self.userDevice, (uint8_t *)&report, sizeof(report));
XCTAssert(status == kIOReturnSuccess, "IOHIDUserDeviceHandleReport:
result = [XCTWaiter waitForExpectations:@[self.testKbcDownEventExpectation] timeout:10];
XCTAssert(result == XCTWaiterResultCompleted, "result:
CFRelease(self.userDevice);
self.userDevice = NULL;
result = [XCTWaiter waitForExpectations:@[self.testKbcUpEventExpectation, self.testNullEventExpectation] timeout:10];
XCTAssert(result == XCTWaiterResultCompleted, "result:
XCTAssert (self.events.count == 0, "Unexpected events:
}
@end