Changeset 15905 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jan 13, 2009 9:26:39 AM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 41526
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/darwin/HostPowerDarwin.cpp
r14527 r15905 24 24 25 25 #include <IOKit/IOMessage.h> 26 #include <IOKit/ps/IOPowerSources.h> 27 #include <IOKit/ps/IOPSKeys.h> 28 29 #define POWER_SOURCE_OUTLET 1 30 #define POWER_SOURCE_BATTERY 2 26 31 27 32 HostPowerServiceDarwin::HostPowerServiceDarwin (VirtualBox *aVirtualBox) 28 : HostPowerService (aVirtualBox), 29 mThread (NULL), 30 mRootPort (MACH_PORT_NULL), 31 mNotifyPort (nil), 32 mRunLoop (nil) 33 : HostPowerService (aVirtualBox) 34 , mThread (NULL) 35 , mRootPort (MACH_PORT_NULL) 36 , mNotifyPort (nil) 37 , mRunLoop (nil) 38 , mCritical (false) 33 39 { 34 40 /* Create the new worker thread. */ … … 57 63 } 58 64 65 59 66 DECLCALLBACK(int) HostPowerServiceDarwin::powerChangeNotificationThread (RTTHREAD ThreadSelf, void *pInstance) 60 67 { 61 68 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> (pInstance); 62 69 63 // OSErr retCode = AEInstallEventHandler(kAEMacPowerMgtEvt, kAEMacLowPowerSaveData, 64 // HostPowerServiceDarwin::lowPowerEventHandler, 65 // pPowerObj, false); 70 /* We have to initial set the critical state of the battery, cause we want 71 * not the HostPowerService to inform about that state when a VM starts. 72 * See lowPowerHandler for more info. */ 73 pPowerObj->checkBatteryCriticalLevel(); 66 74 67 75 /* Register to receive system sleep notifications */ … … 79 87 IONotificationPortGetRunLoopSource (pPowerObj->mNotifyPort), 80 88 kCFRunLoopCommonModes); 89 90 /* Register for all battery change events. The handler will check for low 91 * power events themself. */ 92 CFRunLoopSourceRef runLoopSource = IOPSNotificationCreateRunLoopSource(HostPowerServiceDarwin::lowPowerHandler, 93 pPowerObj); 94 CFRunLoopAddSource(pPowerObj->mRunLoop, 95 runLoopSource, 96 kCFRunLoopCommonModes); 97 81 98 /* Start the run loop. This blocks. */ 82 99 CFRunLoopRun(); 83 84 100 return VINF_SUCCESS; 85 101 } 86 102 87 void HostPowerServiceDarwin::powerChangeNotificationHandler (void *p Data, io_service_t service, natural_t messageType, void *pMessageArgument)88 { 89 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> (p Data);90 // printf( "messageType %08lx, arg %08lx\n", (long unsigned int)messageType, (long unsigned int)pMessageArgument);103 void HostPowerServiceDarwin::powerChangeNotificationHandler (void *pvData, io_service_t service, natural_t messageType, void *pMessageArgument) 104 { 105 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> (pvData); 106 Log (( "powerChangeNotificationHandler: messageType %08lx, arg %08lx\n", (long unsigned int)messageType, (long unsigned int)pMessageArgument)); 91 107 92 108 switch (messageType) … … 132 148 } 133 149 134 OSErr HostPowerServiceDarwin::lowPowerEventHandler (const AppleEvent *event, AppleEvent *replyEvent, long data) 135 { 136 printf ("low power event\n"); 137 LogRel (("low power event\n")); 138 // HostPowerServiceDarwin *pPowerObj = reinterpret_cast<HostPowerServiceDarwin *> (data); 139 // pPowerObj->notify(HostPowerEvent_BatteryLow); 140 return noErr; 141 } 142 150 void HostPowerServiceDarwin::lowPowerHandler (void *pvData) 151 { 152 HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *> (pvData); 153 154 /* Following role for sending the BatteryLow event (5% is critical): 155 * - Not at VM start even if the battery is in an critical state already. 156 * - When the power cord is removed so the power supply change from AC to 157 * battery & the battery is in an critical state nothing is triggered. 158 * This has to be discussed. 159 * - When the power supply is the battery & the state of the battery level 160 * changed from normal to critical. The state transition from critical to 161 * normal triggers nothing. */ 162 bool fCriticalStateChanged = false; 163 pPowerObj->checkBatteryCriticalLevel (&fCriticalStateChanged); 164 if (fCriticalStateChanged) 165 pPowerObj->notify (HostPowerEvent_BatteryLow); 166 } 167 168 void HostPowerServiceDarwin::checkBatteryCriticalLevel (bool *pfCriticalChanged) 169 { 170 CFTypeRef pBlob = IOPSCopyPowerSourcesInfo(); 171 CFArrayRef pSources = IOPSCopyPowerSourcesList (pBlob); 172 173 CFDictionaryRef pSource = NULL; 174 const void *psValue; 175 bool result; 176 int powerSource = POWER_SOURCE_OUTLET; 177 bool critical = false; 178 179 if (CFArrayGetCount (pSources) > 0) 180 { 181 for(int i = 0; i < CFArrayGetCount (pSources); ++i) 182 { 183 pSource = IOPSGetPowerSourceDescription (pBlob, CFArrayGetValueAtIndex (pSources, i)); 184 /* If the source is empty skip over to the next one. */ 185 if(!pSource) 186 continue; 187 /* Skip all power sources which are currently not present like a 188 * second battery. */ 189 if (CFDictionaryGetValue (pSource, CFSTR (kIOPSIsPresentKey)) == kCFBooleanFalse) 190 continue; 191 /* Only internal power types are of interest. */ 192 result = CFDictionaryGetValueIfPresent (pSource, CFSTR (kIOPSTransportTypeKey), &psValue); 193 if (result && 194 CFStringCompare ((CFStringRef)psValue, CFSTR (kIOPSInternalType), 0) == kCFCompareEqualTo) 195 { 196 /* First check which power source we are connect on. */ 197 result = CFDictionaryGetValueIfPresent (pSource, CFSTR (kIOPSPowerSourceStateKey), &psValue); 198 if (result && 199 CFStringCompare ((CFStringRef)psValue, CFSTR (kIOPSACPowerValue), 0) == kCFCompareEqualTo) 200 powerSource = POWER_SOURCE_OUTLET; 201 else if (result && 202 CFStringCompare ((CFStringRef)psValue, CFSTR (kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) 203 powerSource = POWER_SOURCE_BATTERY; 204 205 int curCapacity = 0; 206 int maxCapacity = 1; 207 float remCapacity = 0.0f; 208 209 /* Fetch the current capacity value of the power source */ 210 result = CFDictionaryGetValueIfPresent (pSource, CFSTR (kIOPSCurrentCapacityKey), &psValue); 211 if (result) 212 CFNumberGetValue ((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity); 213 /* Fetch the maximum capacity value of the power source */ 214 result = CFDictionaryGetValueIfPresent (pSource, CFSTR (kIOPSMaxCapacityKey), &psValue); 215 if (result) 216 CFNumberGetValue ((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity); 217 218 /* Calculate the remaining capacity in percent */ 219 remCapacity = ((float)curCapacity/(float)maxCapacity * 100.0); 220 221 /* Check for critical. 5 percent is default. */ 222 int criticalValue = 5; 223 result = CFDictionaryGetValueIfPresent (pSource, CFSTR (kIOPSDeadWarnLevelKey), &psValue); 224 if (result) 225 CFNumberGetValue ((CFNumberRef)psValue, kCFNumberSInt32Type, &criticalValue); 226 critical = (remCapacity < criticalValue); 227 /* We have to take action only if we are on battery, the 228 * previous state wasn't critical, the state has changed & the 229 * user requested that info. */ 230 if (powerSource == POWER_SOURCE_BATTERY && 231 mCritical == false && 232 mCritical != critical && 233 pfCriticalChanged) 234 *pfCriticalChanged = true; 235 Log (("checkBatteryCriticalLevel: Remains: %.0f%% Critical: %d Critical State Changed: %d\n", remCapacity, critical, pfCriticalChanged?*pfCriticalChanged:-1)); 236 } 237 } 238 } 239 /* Save the new state */ 240 mCritical = critical; 241 242 CFRelease (pBlob); 243 CFRelease (pSources); 244 } 245 -
trunk/src/VBox/Main/include/HostPower.h
r15454 r15905 91 91 92 92 static DECLCALLBACK(int) powerChangeNotificationThread (RTTHREAD ThreadSelf, void *pInstance); 93 static void powerChangeNotificationHandler (void *pData, io_service_t service, natural_t messageType, void *pMessageArgument); 94 static OSErr lowPowerEventHandler (const AppleEvent * theAppleEvent, AppleEvent * replyAppleEvent, long refCon); 93 static void powerChangeNotificationHandler (void *pvData, io_service_t service, natural_t messageType, void *pMessageArgument); 94 static void lowPowerHandler (void *pvData); 95 96 void checkBatteryCriticalLevel (bool *pfCriticalChanged = NULL); 95 97 96 98 /* Private member vars */ … … 101 103 io_object_t mNotifierObject; /* Notifier object, used to deregister later */ 102 104 CFRunLoopRef mRunLoop; /* A reference to the local thread run loop */ 105 106 bool mCritical; /* Indicate if the battery was in the critical state last checked */ 103 107 }; 104 108 # endif /* RT_OS_DARWIN */
Note:
See TracChangeset
for help on using the changeset viewer.