IOHIDAggdMetricsPlugIn.cpp [plain text]
#include <new>
#include <AggregateDictionary/ADClient.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/hid/IOHIDSessionFilterPlugIn.h>
#include <IOKit/hid/IOHIDEventSystemPrivate.h>
#include <IOKit/hid/IOHIDEventTypes.h>
#include <IOKit/hid/IOHIDSession.h>
#include <IOKit/hid/IOHIDService.h>
#include <IOKit/hid/IOHIDPrivateKeys.h>
#include <IOKit/hid/IOHIDDisplay.h>
#include <IOKit/hid/IOHIDEventSystemKeys.h>
#include <IOKit/hid/IOHIDUsageTables.h>
#include <IOKit/hid/IOHIDKeys.h>
#include <pthread.h>
#include "IOHIDAggdMetricsPlugIn.h"
#define kAggregateDictionaryKeyboardEnumerationCountKey "com.apple.iokit.hid.keyboard.enumerationCount"
#define kAggregateDictionaryHomeButtonWakeCountKey "com.apple.iokit.hid.homeButton.wakeCount"
#define kIOHIDAggdMetricsPlugInFactory CFUUIDGetConstantUUIDWithBytes(kCFAllocatorSystemDefault, 0x07, 0x2B, 0xC0, 0x77, 0xE9, 0x84, 0x4C, 0x2A, 0xBB, 0x72, 0xD4, 0x76, 0x9C, 0xE4, 0x4F, 0xAF)
extern "C" void * IOHIDAggdMetricsPlugInFactory(CFAllocatorRef allocator, CFUUIDRef typeUUID);
void *IOHIDAggdMetricsPlugInFactory(CFAllocatorRef allocator __unused, CFUUIDRef typeUUID)
{
if (CFEqual(typeUUID, kIOHIDSessionFilterPlugInTypeID)) {
void *p = CFAllocatorAllocate(kCFAllocatorDefault, sizeof(IOHIDAggdMetricsPlugIn), 0);
return new(p) IOHIDAggdMetricsPlugIn(kIOHIDAggdMetricsPlugInFactory);
}
return NULL;
}
IOHIDSessionFilterPlugInInterface IOHIDAggdMetricsPlugIn::sIOHIDAggdMetricsPlugInFtbl =
{
NULL,
IOHIDAggdMetricsPlugIn::QueryInterface,
IOHIDAggdMetricsPlugIn::AddRef,
IOHIDAggdMetricsPlugIn::Release,
IOHIDAggdMetricsPlugIn::filter,
IOHIDAggdMetricsPlugIn::filter, IOHIDAggdMetricsPlugIn::copyEvent,
IOHIDAggdMetricsPlugIn::open,
IOHIDAggdMetricsPlugIn::close,
IOHIDAggdMetricsPlugIn::registerDisplay,
IOHIDAggdMetricsPlugIn::unregisterDisplay,
IOHIDAggdMetricsPlugIn::registerService,
IOHIDAggdMetricsPlugIn::unregisterService,
IOHIDAggdMetricsPlugIn::scheduleWithRunLoop,
IOHIDAggdMetricsPlugIn::unscheduleFromRunLoop,
IOHIDAggdMetricsPlugIn::getPropertyForClient,
IOHIDAggdMetricsPlugIn::setPropertyForClient,
}; IOHIDAggdMetricsPlugIn::IOHIDAggdMetricsPlugIn(CFUUIDRef factoryID)
:
_sessionInterface(&sIOHIDAggdMetricsPlugInFtbl),
_factoryID( static_cast<CFUUIDRef>( CFRetain(factoryID) ) ),
_refCount(1),
_factor(1.0f)
{
CFPlugInAddInstanceForFactory( factoryID );
}
IOHIDAggdMetricsPlugIn::~IOHIDAggdMetricsPlugIn()
{
CFPlugInRemoveInstanceForFactory( _factoryID );
CFRelease( _factoryID );
}
HRESULT IOHIDAggdMetricsPlugIn::QueryInterface( void *self, REFIID iid, LPVOID *ppv )
{
return static_cast<IOHIDAggdMetricsPlugIn *>(self)->QueryInterface(iid, ppv);
}
HRESULT IOHIDAggdMetricsPlugIn::QueryInterface( REFIID iid, LPVOID *ppv )
{
CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes( NULL, iid );
if (CFEqual(interfaceID, kIOHIDSimpleSessionFilterPlugInInterfaceID) || CFEqual(interfaceID, kIOHIDSessionFilterPlugInInterfaceID)) {
AddRef();
*ppv = this;
CFRelease(interfaceID);
return S_OK;
}
if (CFEqual(interfaceID, IUnknownUUID)) {
AddRef();
*ppv = this;
CFRelease(interfaceID);
return S_OK;
}
*ppv = NULL;
CFRelease( interfaceID );
return E_NOINTERFACE;
}
ULONG IOHIDAggdMetricsPlugIn::AddRef( void *self )
{
return static_cast<IOHIDAggdMetricsPlugIn *>(self)->AddRef();
}
ULONG IOHIDAggdMetricsPlugIn::AddRef()
{
_refCount += 1;
return _refCount;
}
ULONG IOHIDAggdMetricsPlugIn::Release( void *self )
{
return static_cast<IOHIDAggdMetricsPlugIn *>(self)->Release();
}
ULONG IOHIDAggdMetricsPlugIn::Release()
{
_refCount -= 1;
if (_refCount == 0) {
delete this;
return 0;
}
return _refCount;
}
boolean_t IOHIDAggdMetricsPlugIn::open(void * self, IOHIDSessionRef session, IOOptionBits options)
{
return true;
}
void IOHIDAggdMetricsPlugIn::close(void * self, IOHIDSessionRef inSession, IOOptionBits options)
{
}
void IOHIDAggdMetricsPlugIn::registerDisplay(void * self, IOHIDDisplayRef display)
{
}
void IOHIDAggdMetricsPlugIn::unregisterDisplay(void * self, IOHIDDisplayRef display)
{
}
void IOHIDAggdMetricsPlugIn::registerService(void * self, IOHIDServiceRef service)
{
static_cast<IOHIDAggdMetricsPlugIn *>(self)->registerService(service);
}
void IOHIDAggdMetricsPlugIn::registerService(IOHIDServiceRef service)
{
if ( IOHIDServiceConformsTo(service, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) )
{
ADClientAddValueForScalarKey(CFSTR(kAggregateDictionaryKeyboardEnumerationCountKey), 1);
}
}
void IOHIDAggdMetricsPlugIn::unregisterService(void * self, IOHIDServiceRef inService)
{
}
void IOHIDAggdMetricsPlugIn::scheduleWithRunLoop(void * self, CFRunLoopRef runLoop, CFStringRef runLoopMode)
{
return;
}
void IOHIDAggdMetricsPlugIn::unscheduleFromRunLoop(void * self, CFRunLoopRef runLoop, CFStringRef runLoopMode)
{
}
CFTypeRef IOHIDAggdMetricsPlugIn::getPropertyForClient(void * self, CFStringRef key, CFTypeRef client)
{
return NULL;
}
void IOHIDAggdMetricsPlugIn::setPropertyForClient(void * self, CFStringRef key, CFTypeRef property, CFTypeRef client)
{
static_cast<IOHIDAggdMetricsPlugIn *>(self)->setPropertyForClient(key, property, client);
}
void IOHIDAggdMetricsPlugIn::setPropertyForClient(CFStringRef key, CFTypeRef property, CFTypeRef client)
{
Boolean factorChange = CFEqual(key, CFSTR(kIOHIDDisplayBrightnessFactorKey)) || CFEqual(key, CFSTR(kIOHIDDisplayBrightnessFactorWithFadeKey));
if ( factorChange ) {
if ( CFGetTypeID(property) == CFNumberGetTypeID() ) {
float factor = _factor;
CFNumberGetValue((CFNumberRef)property, kCFNumberFloatType, &factor);
if ( factor != _factor ) {
_factor = factor;
}
}
}
}
IOHIDEventRef IOHIDAggdMetricsPlugIn::filter(void * self, IOHIDServiceRef sender, IOHIDEventRef event)
{
return static_cast<IOHIDAggdMetricsPlugIn *>(self)->filter(sender, event);
}
IOHIDEventRef IOHIDAggdMetricsPlugIn::filter(IOHIDServiceRef sender, IOHIDEventRef event)
{
float factor = _factor;
CFRetain(event);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
if ( event && (IOHIDEventGetType(event) == kIOHIDEventTypeKeyboard)
&& IOHIDEventGetIntegerValue(event, kIOHIDEventFieldKeyboardDown)
&& (IOHIDEventGetIntegerValue(event, kIOHIDEventFieldKeyboardUsagePage) == kHIDPage_Consumer)
&& (IOHIDEventGetIntegerValue(event, kIOHIDEventFieldKeyboardUsage) == kHIDUsage_Csmr_Menu)
&& (factor == 0.0)) {
ADClientAddValueForScalarKey(CFSTR(kAggregateDictionaryHomeButtonWakeCountKey), 1);
}
CFRelease(event);
});
return event;
}
IOHIDEventRef IOHIDAggdMetricsPlugIn::copyEvent(void * self, IOHIDEventType type, IOHIDEventRef matching, IOOptionBits options)
{
return NULL;
}