TestDigitizerCollection.m [plain text]
//
// TestDigitizerCollection.m
// IOHIDFamily
//
// Created by YG on 10/25/16.
//
//
#import <XCTest/XCTest.h>
#include "IOHIDUnitTestUtility.h"
#import "IOHIDEventSystemTestController.h"
#import "IOHIDUserDeviceTestController.h"
#define FINGER_COLLECTION \
0x09, 0x22, /* Usage (Finger) */\
0xA1, 0x02, /* Collection (Logical) */\
0x05, 0x0D, /* Usage Page (Digitizer) */\
0x09, 0x38, /* Usage (Transducer Index) */\
0x75, 0x04, /* Report Size............. (4) */\
0x95, 0x01, /* Report Count............ (1) */\
0x81, 0x02, /* Input...................(Data, Variable, Absolute) */\
0x09, 0x33, /* Usage (Touch) */\
0x15, 0x00, /* Logical Minimum......... (0) */\
0x25, 0x01, /* Logical Maximum......... (1) */\
0x75, 0x01, /* Report Size............. (1) */\
0x95, 0x01, /* Report Count............ (1) */\
0x81, 0x02, /* Input...................(Data, Variable, Absolute) */\
0x09, 0x32, /* Usage (In Range) */\
0x15, 0x00, /* Logical Minimum......... (0) */\
0x25, 0x01, /* Logical Maximum......... (1) */\
0x75, 0x01, /* Report Size............. (1) */\
0x95, 0x01, /* Report Count............ (1) */\
0x81, 0x02, /* Input...................(Data, Variable, Absolute) */\
0x75, 0x02, /* Report Size............. (2) */\
0x95, 0x01, /* Report Count............ (1) */\
0x81, 0x01, /* Input...................(Constant) */\
0x05, 0x01, /* Usage Page (Generic Desktop) */\
0x09, 0x30, /* Usage (X) */\
0x15, 0x00, /* Logical Minimum......... (0) */\
0x26, 0xFF, 0x7F, /* Logical Maximum......... (32767) */\
0x75, 0x10, /* Report Size............. (16) */\
0x95, 0x01, /* Report Count............ (1) */\
0x81, 0x02, /* Input...................(Data, Variable, Absolute) */\
0x09, 0x31, /* Usage (Y) */\
0x15, 0x00, /* Logical Minimum......... (0) */\
0x25, 0x7F, /* Logical Maximum......... (127) */\
0x75, 0x08, /* Report Size............. (8) */\
0x95, 0x01, /* Report Count............ (1) */\
0x81, 0x02, /* Input...................(Data, Variable, Absolute) */\
0xC0, /* End Collection */
static uint8_t descriptor[] = {
0x05, 0x0d, // Usage Page (Digitizer)
0x09, 0x05, // Usage (Touch Pad)
0xA1, 0x01, // Collection (Application)
0x05, 0x0D, // Usage Page (Digitizer)
FINGER_COLLECTION
FINGER_COLLECTION
FINGER_COLLECTION
FINGER_COLLECTION
FINGER_COLLECTION
FINGER_COLLECTION
FINGER_COLLECTION
FINGER_COLLECTION
FINGER_COLLECTION
FINGER_COLLECTION
0x06, 0x00, 0xFF, // Usage Page (65280)
0x09, 0x23, // Usage 35 (0x23)
0xA1, 0x00, // Collection (Physical)
0x09, 0x01, // Usage 1 (0x1)
0x06, 0x11, 0xFF, // Usage Page (65297)
0x95, 0x01, // Report Count............ (1)
0x75, 0x40, // Report Size............. (64)
0x81, 0x02, // Input...................(Data, Variable, Absolute)
0xC0, // End Collection
0x06, 0x00, 0xFF, // Usage Page (65280)
0x09, 0x16, // Usage 22 (0x16)
0xA1, 0x01, // Collection (Application)
0xC0, // End Collection
0xC0 // End Collection
};
#define kDigitizerReportByteLength 48
uint8_t reports [][kDigitizerReportByteLength] = {
{0x32, 0xe1, 0x40, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xde, 0x34, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x32, 0xe1, 0x40, 0x3f, 0x35, 0xbd, 0x37, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x5c, 0x47, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x32, 0xe1, 0x40, 0x3f, 0x35, 0xbd, 0x37, 0x3f, 0x38, 0x98, 0x2e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x60, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x22, 0xe1, 0x40, 0x3f, 0x35, 0xbd, 0x37, 0x3f, 0x38, 0x98, 0x2e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x65, 0x66, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x02, 0xe1, 0x40, 0x3f, 0x25, 0xbd, 0x37, 0x3f, 0x38, 0x98, 0x2e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x7e, 0x6c, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x05, 0xbd, 0x37, 0x3f, 0x38, 0x98, 0x2e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x88, 0x72, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x32, 0x2d, 0x41, 0x3f, 0x08, 0x98, 0x2e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xd4, 0x7e, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x32, 0x2d, 0x41, 0x3f, 0x35, 0xcc, 0x37, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x6f, 0x91, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x02, 0x2d, 0x41, 0x3f, 0x35, 0xcc, 0x37, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xe2, 0xa3, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x05, 0xcc, 0x37, 0x3f, 0x38, 0x11, 0x2f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x15, 0xaa, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x08, 0x11, 0x2f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x95, 0xc2, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x32, 0x3c, 0x41, 0x3f, 0x35, 0xae, 0x37, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x24, 0xcf, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x02, 0x3c, 0x41, 0x3f, 0x35, 0xae, 0x37, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x6f, 0xdb, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x25, 0xae, 0x37, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x96, 0xe1, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x05, 0xae, 0x37, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xab, 0xe7, 0x51, 0xc9, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xab, 0xe7, 0x51, 0xc9, 0x01, 0x00, 0x00}
};
@interface TestDigitizerCollection : XCTestCase
@property IOHIDEventSystemTestController * eventController;
@property IOHIDUserDeviceTestController * sourceController;
@property dispatch_queue_t eventControllerQueue;
@property dispatch_queue_t rootQueue;
@end
@implementation TestDigitizerCollection
- (void)setUp {
[super setUp];
self.rootQueue = IOHIDUnitTestCreateRootQueue(31, 2);
self.eventControllerQueue = dispatch_queue_create_with_target ("IOHIDEventSystemTestController", DISPATCH_QUEUE_SERIAL, self.rootQueue);
HIDXCTAssertAndThrowTrue(self.eventControllerQueue != nil);
NSData * descriptorData = [[NSData alloc] initWithBytes:descriptor length:sizeof(descriptor)];
NSString * uniqueID = [[[NSUUID alloc] init] UUIDString];
self.sourceController = [[IOHIDUserDeviceTestController alloc] initWithDescriptor:descriptorData DeviceUniqueID:uniqueID andQueue:nil];
HIDXCTAssertAndThrowTrue(self.sourceController != nil);
self.eventController = [[IOHIDEventSystemTestController alloc] initWithDeviceUniqueID:uniqueID AndQueue:self.eventControllerQueue];
HIDXCTAssertAndThrowTrue(self.sourceController != nil);
}
- (void)tearDown {
[self.eventController invalidate];
[self.sourceController invalidate];
@autoreleasepool {
self.eventController = nil;
self.sourceController = nil;
}
[super tearDown];
}
- (void)testDigitizerCollection {
IOReturn status;
for (NSUInteger index = 0; index < sizeof(reports) / kDigitizerReportByteLength; index++) {
NSData * reportData = [[NSData alloc] initWithBytes:&reports[index][0] length: kDigitizerReportByteLength];
status = [self.sourceController handleReport:reportData withInterval:2000];
XCTAssert(status == kIOReturnSuccess, "handleReport: }
// Allow event to be dispatched
usleep(kDefaultReportDispatchCompletionTime);
// Check if event system reset occur
XCTAssert(self.eventController.eventSystemResetCount == 0, "IOHIDEventSystem resetCount:
// Make copy
NSArray *events = nil;
@synchronized (self.eventController.events) {
events = [self.eventController.events copy];
}
EVENTS_STATS stats = [IOHIDEventSystemTestController getEventsStats:events];
XCTAssertTrue(stats.totalCount == (sizeof(reports) / kDigitizerReportByteLength),
"events count:
HIDTestEventLatency(stats);
NSInteger touchState [11];
memset (touchState, 0, sizeof(touchState));
for (NSUInteger eventIndex = 0 ; eventIndex < events.count ; ++eventIndex) {
NSInteger curTouchState [11];
memset (curTouchState, 0, sizeof(touchState));
IOHIDEventRef event = (__bridge IOHIDEventRef)(events[eventIndex]);
NSArray* children = (NSArray*)IOHIDEventGetChildren (event);
for (NSUInteger childIndex = 0 ; childIndex < children.count ; ++childIndex) {
IOHIDEventRef child = (__bridge IOHIDEventRef)children[childIndex];
CFIndex transducerIndex = IOHIDEventGetIntegerValue(child, kIOHIDEventFieldDigitizerIndex);
XCTAssertTrue(transducerIndex <= 10, "Transducer index out of range! Event index: CFIndex transducerTouch = IOHIDEventGetIntegerValue(child, kIOHIDEventFieldDigitizerTouch);
curTouchState[transducerIndex] = transducerTouch + 1;
}
//
// Basic logic is track transition from touch to not present
//
for (NSUInteger transducerIndex = 0; transducerIndex < sizeof(touchState); ++transducerIndex) {
XCTAssertFalse(touchState[transducerIndex] == 2 && curTouchState[transducerIndex] == 0, "Transducer touch lost! Event index: }
memcpy(touchState, curTouchState, sizeof (touchState));
}
}
@end