Changeset 46775 in vbox for trunk/src/VBox/Main/src-server/darwin
- Timestamp:
- Jun 25, 2013 12:37:57 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 86706
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/darwin/HostPowerDarwin.cpp
r44529 r46775 5 5 6 6 /* 7 * Copyright (C) 2008-201 0Oracle Corporation7 * Copyright (C) 2008-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 26 26 #define POWER_SOURCE_BATTERY 2 27 27 28 HostPowerServiceDarwin::HostPowerServiceDarwin 29 : HostPowerService 30 , mThread 31 , mRootPort 32 , mNotifyPort 33 , mRunLoop 34 , mCritical 28 HostPowerServiceDarwin::HostPowerServiceDarwin(VirtualBox *aVirtualBox) 29 : HostPowerService(aVirtualBox) 30 , mThread(NULL) 31 , mRootPort(MACH_PORT_NULL) 32 , mNotifyPort(nil) 33 , mRunLoop(nil) 34 , mCritical(false) 35 35 { 36 36 /* Create the new worker thread. */ 37 int rc = RTThreadCreate 38 37 int rc = RTThreadCreate(&mThread, HostPowerServiceDarwin::powerChangeNotificationThread, this, 65536, 38 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "MainPower"); 39 39 40 40 if (RT_FAILURE(rc)) 41 LogFlow 41 LogFlow(("RTThreadCreate failed with %Rrc\n", rc)); 42 42 } 43 43 … … 45 45 { 46 46 /* Jump out of the run loop. */ 47 CFRunLoopStop 47 CFRunLoopStop(mRunLoop); 48 48 /* Remove the sleep notification port from the application runloop. */ 49 CFRunLoopRemoveSource 50 IONotificationPortGetRunLoopSource(mNotifyPort),51 49 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), 50 IONotificationPortGetRunLoopSource(mNotifyPort), 51 kCFRunLoopCommonModes); 52 52 /* Deregister for system sleep notifications. */ 53 IODeregisterForSystemPower 53 IODeregisterForSystemPower(&mNotifierObject); 54 54 /* IORegisterForSystemPower implicitly opens the Root Power Domain 55 55 * IOService so we close it here. */ 56 IOServiceClose 56 IOServiceClose(mRootPort); 57 57 /* Destroy the notification port allocated by IORegisterForSystemPower */ 58 IONotificationPortDestroy 59 } 60 61 62 DECLCALLBACK(int) HostPowerServiceDarwin::powerChangeNotificationThread 63 { 64 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> 58 IONotificationPortDestroy(mNotifyPort); 59 } 60 61 62 DECLCALLBACK(int) HostPowerServiceDarwin::powerChangeNotificationThread(RTTHREAD /* ThreadSelf */, void *pInstance) 63 { 64 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *>(pInstance); 65 65 66 66 /* We have to initial set the critical state of the battery, cause we want … … 70 70 71 71 /* Register to receive system sleep notifications */ 72 pPowerObj->mRootPort = IORegisterForSystemPower 73 74 72 pPowerObj->mRootPort = IORegisterForSystemPower(pPowerObj, &pPowerObj->mNotifyPort, 73 HostPowerServiceDarwin::powerChangeNotificationHandler, 74 &pPowerObj->mNotifierObject); 75 75 if (pPowerObj->mRootPort == MACH_PORT_NULL) 76 76 { 77 LogFlow 77 LogFlow(("IORegisterForSystemPower failed\n")); 78 78 return VERR_NOT_SUPPORTED; 79 79 } 80 80 pPowerObj->mRunLoop = CFRunLoopGetCurrent(); 81 81 /* Add the notification port to the application runloop */ 82 CFRunLoopAddSource 83 IONotificationPortGetRunLoopSource(pPowerObj->mNotifyPort),84 82 CFRunLoopAddSource(pPowerObj->mRunLoop, 83 IONotificationPortGetRunLoopSource(pPowerObj->mNotifyPort), 84 kCFRunLoopCommonModes); 85 85 86 86 /* Register for all battery change events. The handler will check for low … … 97 97 } 98 98 99 void HostPowerServiceDarwin::powerChangeNotificationHandler 100 { 101 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> 102 Log 99 void HostPowerServiceDarwin::powerChangeNotificationHandler(void *pvData, io_service_t /* service */, natural_t messageType, void *pMessageArgument) 100 { 101 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *>(pvData); 102 Log(( "powerChangeNotificationHandler: messageType %08lx, arg %08lx\n", (long unsigned int)messageType, (long unsigned int)pMessageArgument)); 103 103 104 104 switch (messageType) … … 114 114 * IOAllowPowerChange or IOCancelPowerChange, the system will 115 115 * wait 30 seconds then go to sleep. */ 116 IOAllowPowerChange (pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument));116 IOAllowPowerChange(pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument)); 117 117 break; 118 118 } … … 120 120 { 121 121 /* The system will go for sleep. */ 122 pPowerObj->notify (HostPowerEvent_Suspend);122 pPowerObj->notify(Reason_HostSuspend); 123 123 /* If you do not call IOAllowPowerChange or IOCancelPowerChange to 124 124 * acknowledge this message, sleep will be delayed by 30 seconds. 125 125 * NOTE: If you call IOCancelPowerChange to deny sleep it returns 126 126 * kIOReturnSuccess, however the system WILL still go to sleep. */ 127 IOAllowPowerChange (pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument));127 IOAllowPowerChange(pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument)); 128 128 break; 129 129 } … … 136 136 { 137 137 /* System has finished the wake up process. */ 138 pPowerObj->notify (HostPowerEvent_Resume);138 pPowerObj->notify(Reason_HostResume); 139 139 break; 140 140 } … … 144 144 } 145 145 146 void HostPowerServiceDarwin::lowPowerHandler 147 { 148 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> 149 150 /* Following role for sending the BatteryLow event 146 void HostPowerServiceDarwin::lowPowerHandler(void *pvData) 147 { 148 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *>(pvData); 149 150 /* Following role for sending the BatteryLow event(5% is critical): 151 151 * - Not at VM start even if the battery is in an critical state already. 152 152 * - When the power cord is removed so the power supply change from AC to … … 157 157 * normal triggers nothing. */ 158 158 bool fCriticalStateChanged = false; 159 pPowerObj->checkBatteryCriticalLevel 159 pPowerObj->checkBatteryCriticalLevel(&fCriticalStateChanged); 160 160 if (fCriticalStateChanged) 161 pPowerObj->notify (HostPowerEvent_BatteryLow);162 } 163 164 void HostPowerServiceDarwin::checkBatteryCriticalLevel 161 pPowerObj->notify(Reason_HostBatteryLow); 162 } 163 164 void HostPowerServiceDarwin::checkBatteryCriticalLevel(bool *pfCriticalChanged) 165 165 { 166 166 CFTypeRef pBlob = IOPSCopyPowerSourcesInfo(); 167 CFArrayRef pSources = IOPSCopyPowerSourcesList 167 CFArrayRef pSources = IOPSCopyPowerSourcesList(pBlob); 168 168 169 169 CFDictionaryRef pSource = NULL; … … 173 173 bool critical = false; 174 174 175 if (CFArrayGetCount 175 if (CFArrayGetCount(pSources) > 0) 176 176 { 177 for (int i = 0; i < CFArrayGetCount 177 for (int i = 0; i < CFArrayGetCount(pSources); ++i) 178 178 { 179 pSource = IOPSGetPowerSourceDescription (pBlob, CFArrayGetValueAtIndex(pSources, i));179 pSource = IOPSGetPowerSourceDescription(pBlob, CFArrayGetValueAtIndex(pSources, i)); 180 180 /* If the source is empty skip over to the next one. */ 181 181 if (!pSource) … … 183 183 /* Skip all power sources which are currently not present like a 184 184 * second battery. */ 185 if (CFDictionaryGetValue (pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse)185 if (CFDictionaryGetValue(pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse) 186 186 continue; 187 187 /* Only internal power types are of interest. */ 188 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSTransportTypeKey), &psValue);188 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTransportTypeKey), &psValue); 189 189 if (result && 190 CFStringCompare ((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo)190 CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo) 191 191 { 192 192 /* First check which power source we are connect on. */ 193 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue);193 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue); 194 194 if (result && 195 CFStringCompare ((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo)195 CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) 196 196 powerSource = POWER_SOURCE_OUTLET; 197 197 else if (result && 198 CFStringCompare ((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo)198 CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) 199 199 powerSource = POWER_SOURCE_BATTERY; 200 200 … … 204 204 205 205 /* Fetch the current capacity value of the power source */ 206 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSCurrentCapacityKey), &psValue);206 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSCurrentCapacityKey), &psValue); 207 207 if (result) 208 CFNumberGetValue 208 CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity); 209 209 /* Fetch the maximum capacity value of the power source */ 210 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSMaxCapacityKey), &psValue);210 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSMaxCapacityKey), &psValue); 211 211 if (result) 212 CFNumberGetValue 212 CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity); 213 213 214 214 /* Calculate the remaining capacity in percent */ … … 217 217 /* Check for critical. 5 percent is default. */ 218 218 int criticalValue = 5; 219 result = CFDictionaryGetValueIfPresent (pSource, CFSTR(kIOPSDeadWarnLevelKey), &psValue);219 result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSDeadWarnLevelKey), &psValue); 220 220 if (result) 221 CFNumberGetValue 221 CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &criticalValue); 222 222 critical = (remCapacity < criticalValue); 223 223 /* We have to take action only if we are on battery, the … … 229 229 pfCriticalChanged) 230 230 *pfCriticalChanged = true; 231 Log 231 Log(("checkBatteryCriticalLevel: Remains: %d.%d%% Critical: %d Critical State Changed: %d\n", (int)remCapacity, (int)(remCapacity * 10) % 10, critical, pfCriticalChanged?*pfCriticalChanged:-1)); 232 232 } 233 233 } … … 236 236 mCritical = critical; 237 237 238 CFRelease 239 CFRelease 240 } 241 238 CFRelease(pBlob); 239 CFRelease(pSources); 240 } 241
Note:
See TracChangeset
for help on using the changeset viewer.