1/* 2 * IOHIDAggdMetricsPlugIn.cpp 3 * IOHIDEventSystemPlugIns 4 * 5 * Created by Rob Yepez on 05/21/2013. 6 * Copyright 2013 Apple Inc. All rights reserved. 7 * 8 */ 9 10#include <new> 11#include <AggregateDictionary/ADClient.h> 12#include <CoreFoundation/CoreFoundation.h> 13#include <IOKit/hid/IOHIDSessionFilterPlugIn.h> 14#include <IOKit/hid/IOHIDEventSystemPrivate.h> 15#include <IOKit/hid/IOHIDEventTypes.h> 16#include <IOKit/hid/IOHIDSession.h> 17#include <IOKit/hid/IOHIDService.h> 18#include <IOKit/hid/IOHIDPrivateKeys.h> 19#include <IOKit/hid/IOHIDDisplay.h> 20#include <IOKit/hid/IOHIDEventSystemKeys.h> 21#include <IOKit/hid/IOHIDUsageTables.h> 22#include <IOKit/hid/IOHIDKeys.h> 23#include <pthread.h> 24#include "IOHIDAggdMetricsPlugIn.h" 25 26 27#define kAggregateDictionaryKeyboardEnumerationCountKey "com.apple.iokit.hid.keyboard.enumerationCount" 28#define kAggregateDictionaryHomeButtonWakeCountKey "com.apple.iokit.hid.homeButton.wakeCount" 29 30// 072BC077-E984-4C2A-BB72-D4769CE44FAF 31#define kIOHIDAggdMetricsPlugInFactory CFUUIDGetConstantUUIDWithBytes(kCFAllocatorSystemDefault, 0x07, 0x2B, 0xC0, 0x77, 0xE9, 0x84, 0x4C, 0x2A, 0xBB, 0x72, 0xD4, 0x76, 0x9C, 0xE4, 0x4F, 0xAF) 32 33extern "C" void * IOHIDAggdMetricsPlugInFactory(CFAllocatorRef allocator, CFUUIDRef typeUUID); 34 35//------------------------------------------------------------------------------ 36// IOHIDAggdMetricsPlugInFactory 37//------------------------------------------------------------------------------ 38// Implementation of the factory function for this type. 39void *IOHIDAggdMetricsPlugInFactory(CFAllocatorRef allocator __unused, CFUUIDRef typeUUID) 40{ 41 // If correct type is being requested, allocate an 42 // instance of TestType and return the IUnknown interface. 43 if (CFEqual(typeUUID, kIOHIDSessionFilterPlugInTypeID)) { 44 void *p = CFAllocatorAllocate(kCFAllocatorDefault, sizeof(IOHIDAggdMetricsPlugIn), 0); 45 return new(p) IOHIDAggdMetricsPlugIn(kIOHIDAggdMetricsPlugInFactory); 46 } 47 // If the requested type is incorrect, return NULL. 48 return NULL; 49} 50// The IOHIDAggdMetricsPlugIn function table. 51IOHIDSessionFilterPlugInInterface IOHIDAggdMetricsPlugIn::sIOHIDAggdMetricsPlugInFtbl = 52{ 53 // Required padding for COM 54 NULL, 55 // These three are the required COM functions 56 IOHIDAggdMetricsPlugIn::QueryInterface, 57 IOHIDAggdMetricsPlugIn::AddRef, 58 IOHIDAggdMetricsPlugIn::Release, 59 // IOHIDSimpleSessionFilterPlugInInterface functions 60 IOHIDAggdMetricsPlugIn::filter, 61 IOHIDAggdMetricsPlugIn::filter, // filterCopyEvent 62 IOHIDAggdMetricsPlugIn::copyEvent, 63 // IOHIDSessionFilterPlugInInterface functions 64 IOHIDAggdMetricsPlugIn::open, 65 IOHIDAggdMetricsPlugIn::close, 66 IOHIDAggdMetricsPlugIn::registerDisplay, 67 IOHIDAggdMetricsPlugIn::unregisterDisplay, 68 IOHIDAggdMetricsPlugIn::registerService, 69 IOHIDAggdMetricsPlugIn::unregisterService, 70 IOHIDAggdMetricsPlugIn::scheduleWithRunLoop, 71 IOHIDAggdMetricsPlugIn::unscheduleFromRunLoop, 72 IOHIDAggdMetricsPlugIn::getPropertyForClient, 73 IOHIDAggdMetricsPlugIn::setPropertyForClient, 74}; // Interface implementation 75//------------------------------------------------------------------------------ 76// IOHIDAggdMetricsPlugIn::IOHIDAggdMetricsPlugIn 77//------------------------------------------------------------------------------ 78IOHIDAggdMetricsPlugIn::IOHIDAggdMetricsPlugIn(CFUUIDRef factoryID) 79: 80_sessionInterface(&sIOHIDAggdMetricsPlugInFtbl), 81_factoryID( static_cast<CFUUIDRef>( CFRetain(factoryID) ) ), 82_refCount(1), 83_factor(1.0f) 84{ 85 CFPlugInAddInstanceForFactory( factoryID ); 86} 87//------------------------------------------------------------------------------ 88// IOHIDAggdMetricsPlugIn::IOHIDAggdMetricsPlugIn 89//------------------------------------------------------------------------------ 90IOHIDAggdMetricsPlugIn::~IOHIDAggdMetricsPlugIn() 91{ 92 CFPlugInRemoveInstanceForFactory( _factoryID ); 93 CFRelease( _factoryID ); 94} 95//------------------------------------------------------------------------------ 96// IOHIDAggdMetricsPlugIn::QueryInterface 97//------------------------------------------------------------------------------ 98HRESULT IOHIDAggdMetricsPlugIn::QueryInterface( void *self, REFIID iid, LPVOID *ppv ) 99{ 100 return static_cast<IOHIDAggdMetricsPlugIn *>(self)->QueryInterface(iid, ppv); 101} 102// Implementation of the IUnknown QueryInterface function. 103HRESULT IOHIDAggdMetricsPlugIn::QueryInterface( REFIID iid, LPVOID *ppv ) 104{ 105 // Create a CoreFoundation UUIDRef for the requested interface. 106 CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes( NULL, iid ); 107 // Test the requested ID against the valid interfaces. 108 if (CFEqual(interfaceID, kIOHIDSimpleSessionFilterPlugInInterfaceID) || CFEqual(interfaceID, kIOHIDSessionFilterPlugInInterfaceID)) { 109 AddRef(); 110 *ppv = this; 111 CFRelease(interfaceID); 112 return S_OK; 113 } 114 if (CFEqual(interfaceID, IUnknownUUID)) { 115 // If the IUnknown interface was requested, same as above. 116 AddRef(); 117 *ppv = this; 118 CFRelease(interfaceID); 119 return S_OK; 120 } 121 // Requested interface unknown, bail with error. 122 *ppv = NULL; 123 CFRelease( interfaceID ); 124 return E_NOINTERFACE; 125} 126//------------------------------------------------------------------------------ 127// IOHIDAggdMetricsPlugIn::AddRef 128//------------------------------------------------------------------------------ 129ULONG IOHIDAggdMetricsPlugIn::AddRef( void *self ) 130{ 131 return static_cast<IOHIDAggdMetricsPlugIn *>(self)->AddRef(); 132} 133ULONG IOHIDAggdMetricsPlugIn::AddRef() 134{ 135 _refCount += 1; 136 return _refCount; 137} 138//------------------------------------------------------------------------------ 139// IOHIDAggdMetricsPlugIn::Release 140//------------------------------------------------------------------------------ 141ULONG IOHIDAggdMetricsPlugIn::Release( void *self ) 142{ 143 return static_cast<IOHIDAggdMetricsPlugIn *>(self)->Release(); 144} 145ULONG IOHIDAggdMetricsPlugIn::Release() 146{ 147 _refCount -= 1; 148 if (_refCount == 0) { 149 delete this; 150 return 0; 151 } 152 return _refCount; 153} 154//------------------------------------------------------------------------------ 155// IOHIDAggdMetricsPlugIn::open 156//------------------------------------------------------------------------------ 157boolean_t IOHIDAggdMetricsPlugIn::open(void * self, IOHIDSessionRef session, IOOptionBits options) 158{ 159 return true; 160} 161//------------------------------------------------------------------------------ 162// IOHIDAggdMetricsPlugIn::close 163//------------------------------------------------------------------------------ 164void IOHIDAggdMetricsPlugIn::close(void * self, IOHIDSessionRef inSession, IOOptionBits options) 165{ 166} 167//------------------------------------------------------------------------------ 168// IOHIDAggdMetricsPlugIn::registerDisplay 169//------------------------------------------------------------------------------ 170void IOHIDAggdMetricsPlugIn::registerDisplay(void * self, IOHIDDisplayRef display) 171{ 172} 173//------------------------------------------------------------------------------ 174// IOHIDAggdMetricsPlugIn::unregisterDisplay 175//------------------------------------------------------------------------------ 176void IOHIDAggdMetricsPlugIn::unregisterDisplay(void * self, IOHIDDisplayRef display) 177{ 178} 179//------------------------------------------------------------------------------ 180// IOHIDAggdMetricsPlugIn::registerService 181//------------------------------------------------------------------------------ 182void IOHIDAggdMetricsPlugIn::registerService(void * self, IOHIDServiceRef service) 183{ 184 static_cast<IOHIDAggdMetricsPlugIn *>(self)->registerService(service); 185} 186void IOHIDAggdMetricsPlugIn::registerService(IOHIDServiceRef service) 187{ 188 if ( IOHIDServiceConformsTo(service, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) ) 189 { 190 ADClientAddValueForScalarKey(CFSTR(kAggregateDictionaryKeyboardEnumerationCountKey), 1); 191 } 192} 193//------------------------------------------------------------------------------ 194// IOHIDAggdMetricsPlugIn::unregisterService 195//------------------------------------------------------------------------------ 196void IOHIDAggdMetricsPlugIn::unregisterService(void * self, IOHIDServiceRef inService) 197{ 198} 199//------------------------------------------------------------------------------ 200// IOHIDAggdMetricsPlugIn::scheduleWithRunLoop 201//------------------------------------------------------------------------------ 202void IOHIDAggdMetricsPlugIn::scheduleWithRunLoop(void * self, CFRunLoopRef runLoop, CFStringRef runLoopMode) 203{ 204 return; 205} 206//------------------------------------------------------------------------------ 207// IOHIDAggdMetricsPlugIn::unscheduleFromRunLoop 208//------------------------------------------------------------------------------ 209void IOHIDAggdMetricsPlugIn::unscheduleFromRunLoop(void * self, CFRunLoopRef runLoop, CFStringRef runLoopMode) 210{ 211} 212//------------------------------------------------------------------------------ 213// IOHIDAggdMetricsPlugIn::getPropertyForClient 214//------------------------------------------------------------------------------ 215CFTypeRef IOHIDAggdMetricsPlugIn::getPropertyForClient(void * self, CFStringRef key, CFTypeRef client) 216{ 217 return NULL; 218} 219//------------------------------------------------------------------------------ 220// IOHIDAggdMetricsPlugIn::setPropertyForClient 221//------------------------------------------------------------------------------ 222void IOHIDAggdMetricsPlugIn::setPropertyForClient(void * self, CFStringRef key, CFTypeRef property, CFTypeRef client) 223{ 224 static_cast<IOHIDAggdMetricsPlugIn *>(self)->setPropertyForClient(key, property, client); 225} 226void IOHIDAggdMetricsPlugIn::setPropertyForClient(CFStringRef key, CFTypeRef property, CFTypeRef client) 227{ 228 Boolean factorChange = CFEqual(key, CFSTR(kIOHIDDisplayBrightnessFactorKey)) || CFEqual(key, CFSTR(kIOHIDDisplayBrightnessFactorWithFadeKey)); 229 if ( factorChange ) { 230 if ( CFGetTypeID(property) == CFNumberGetTypeID() ) { 231 float factor = _factor; 232 CFNumberGetValue((CFNumberRef)property, kCFNumberFloatType, &factor); 233 // After application, did anything change relating to the display 234 if ( factor != _factor ) { 235 _factor = factor; 236 } 237 } 238 } 239} 240//------------------------------------------------------------------------------ 241// IOHIDAggdMetricsPlugIn::filter 242//------------------------------------------------------------------------------ 243IOHIDEventRef IOHIDAggdMetricsPlugIn::filter(void * self, IOHIDServiceRef sender, IOHIDEventRef event) 244{ 245 return static_cast<IOHIDAggdMetricsPlugIn *>(self)->filter(sender, event); 246} 247IOHIDEventRef IOHIDAggdMetricsPlugIn::filter(IOHIDServiceRef sender, IOHIDEventRef event) 248{ 249 float factor = _factor; 250 CFRetain(event); 251 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 252 253 if ( event && (IOHIDEventGetType(event) == kIOHIDEventTypeKeyboard) 254 && IOHIDEventGetIntegerValue(event, kIOHIDEventFieldKeyboardDown) 255 && (IOHIDEventGetIntegerValue(event, kIOHIDEventFieldKeyboardUsagePage) == kHIDPage_Consumer) 256 && (IOHIDEventGetIntegerValue(event, kIOHIDEventFieldKeyboardUsage) == kHIDUsage_Csmr_Menu) 257 && (factor == 0.0)) { 258 259 ADClientAddValueForScalarKey(CFSTR(kAggregateDictionaryHomeButtonWakeCountKey), 1); 260 } 261 262 CFRelease(event); 263 }); 264 265 return event; 266} 267//------------------------------------------------------------------------------ 268// IOHIDAggdMetricsPlugIn::copyEvent 269//------------------------------------------------------------------------------ 270IOHIDEventRef IOHIDAggdMetricsPlugIn::copyEvent(void * self, IOHIDEventType type, IOHIDEventRef matching, IOOptionBits options) 271{ 272 return NULL; 273} 274