VirtualBox

Changeset 14710

Show
Ignore:
Timestamp:
11/27/08 16:13:46 (1 month ago)
Author:
vboxsync
Message:

Devices-OSX: added ACPI power reporting (#3342)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/VBox/Devices/PC/DrvACPI.cpp

    r14464 r14710  
    4141#endif 
    4242 
     43#ifdef RT_OS_DARWIN 
     44# include <Carbon/Carbon.h> 
     45# include <IOKit/ps/IOPowerSources.h> 
     46# include <IOKit/ps/IOPSKeys.h> 
     47#endif 
     48 
    4349#include "Builtins.h" 
    4450 
     
    179185        fclose(statusFile); 
    180186    } 
    181 #else /* !RT_OS_LINUX either - what could this be? */ 
     187#elif defined (RT_OS_DARWIN) /* !RT_OS_LINUX */ 
     188    *pPowerSource = PDM_ACPI_POWER_SOURCE_UNKNOWN; 
     189 
     190    CFTypeRef pBlob = IOPSCopyPowerSourcesInfo(); 
     191    CFArrayRef pSources = IOPSCopyPowerSourcesList(pBlob); 
     192 
     193    CFDictionaryRef pSource = NULL; 
     194    const void *psValue; 
     195    bool result; 
     196 
     197    if (CFArrayGetCount(pSources) > 0) 
     198    { 
     199        for(int i = 0; i < CFArrayGetCount(pSources); ++i) 
     200        { 
     201            pSource = IOPSGetPowerSourceDescription(pBlob, CFArrayGetValueAtIndex(pSources, i)); 
     202            /* If the source is empty skip over to the next one. */ 
     203            if(!pSource) 
     204                continue; 
     205            /* Skip all power sources which are currently not present like a 
     206             * second battery. */ 
     207            if (CFDictionaryGetValue(pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse) 
     208                continue; 
     209            /* Only internal power types are of interest. */ 
     210            result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTransportTypeKey), &psValue); 
     211            if (result && 
     212                CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo) 
     213            { 
     214                /* Check which power source we are connect on. */ 
     215                result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue); 
     216                if (result && 
     217                    CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) 
     218                    *pPowerSource = PDM_ACPI_POWER_SOURCE_OUTLET; 
     219                else if (result && 
     220                         CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) 
     221                    *pPowerSource = PDM_ACPI_POWER_SOURCE_BATTERY; 
     222            } 
     223        } 
     224    } 
     225    CFRelease(pBlob); 
     226    CFRelease(pSources); 
     227#else /* !RT_OS_DARWIN either - what could this be? */ 
    182228    *pPowerSource = PDM_ACPI_POWER_SOURCE_OUTLET; 
    183229#endif /* !RT_OS_WINDOWS */ 
     
    413459        *pu32PresentRate = (uint32_t)(((float)presentRateTotal / (float)maxCapacityTotal) * 1000); 
    414460    } 
    415 #endif /* RT_OS_LINUX */ 
     461#elif defined(RT_OS_DARWIN) 
     462    CFTypeRef pBlob = IOPSCopyPowerSourcesInfo(); 
     463    CFArrayRef pSources = IOPSCopyPowerSourcesList(pBlob); 
     464 
     465    CFDictionaryRef pSource = NULL; 
     466    const void *psValue; 
     467    bool result; 
     468 
     469    if (CFArrayGetCount(pSources) > 0) 
     470    { 
     471        for(int i = 0; i < CFArrayGetCount(pSources); ++i) 
     472        { 
     473            pSource = IOPSGetPowerSourceDescription(pBlob, CFArrayGetValueAtIndex(pSources, i)); 
     474            /* If the source is empty skip over to the next one. */ 
     475            if(!pSource) 
     476                continue; 
     477            /* Skip all power sources which are currently not present like a 
     478             * second battery. */ 
     479            if (CFDictionaryGetValue(pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse) 
     480                continue; 
     481            /* Only internal power types are of interest. */ 
     482            result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTransportTypeKey), &psValue); 
     483            if (result && 
     484                CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo) 
     485            { 
     486                PDMACPIPOWERSOURCE powerSource = PDM_ACPI_POWER_SOURCE_UNKNOWN; 
     487                /* First check which power source we are connect on. */ 
     488                result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue); 
     489                if (result && 
     490                    CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) 
     491                    powerSource = PDM_ACPI_POWER_SOURCE_OUTLET; 
     492                else if (result && 
     493                         CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) 
     494                    powerSource = PDM_ACPI_POWER_SOURCE_BATTERY; 
     495 
     496                /* At this point the power source is present. */ 
     497                *pfPresent = true; 
     498                *penmBatteryState = PDM_ACPI_BAT_STATE_CHARGED; 
     499 
     500                int curCapacity = 0; 
     501                int maxCapacity = 1; 
     502                float remCapacity = 0.0f; 
     503 
     504                /* Fetch the current capacity value of the power source */ 
     505                result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSCurrentCapacityKey), &psValue); 
     506                if (result) 
     507                    CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity); 
     508                /* Fetch the maximum capacity value of the power source */ 
     509                result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSMaxCapacityKey), &psValue); 
     510                if (result) 
     511                    CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity); 
     512 
     513                /* Calculate the remaining capacity in percent */ 
     514                remCapacity = ((float)curCapacity/(float)maxCapacity * PDM_ACPI_BAT_CAPACITY_MAX); 
     515                *penmRemainingCapacity = (PDMACPIBATCAPACITY)remCapacity; 
     516 
     517                if (powerSource == PDM_ACPI_POWER_SOURCE_BATTERY) 
     518                { 
     519                    /* If we are on battery power we are discharging in every 
     520                     * case */ 
     521                    *penmBatteryState = PDM_ACPI_BAT_STATE_DISCHARGING; 
     522                    int timeToEmpty = -1; 
     523                    /* Get the time till the battery source will be empty */ 
     524                    result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTimeToEmptyKey), &psValue); 
     525                    if (result) 
     526                        CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &timeToEmpty); 
     527                    if (timeToEmpty != -1) 
     528                        /* 0...1000 */ 
     529                        *pu32PresentRate = (uint32_t)roundf((remCapacity / ((float)timeToEmpty/60.0)) * 10.0); 
     530                } 
     531 
     532                if (powerSource == PDM_ACPI_POWER_SOURCE_OUTLET && 
     533                    CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsChargingKey), &psValue)) 
     534                { 
     535                    /* We are running on an AC power source, but we also have a 
     536                     * battery power source present. */ 
     537                    if (CFBooleanGetValue((CFBooleanRef)psValue) > 0) 
     538                    { 
     539                        /* This means charging. */ 
     540                        *penmBatteryState = PDM_ACPI_BAT_STATE_CHARGING; 
     541                        int timeToFull = -1; 
     542                        /* Get the time till the battery source will be charged */ 
     543                        result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTimeToFullChargeKey), &psValue); 
     544                        if (result) 
     545                            CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &timeToFull); 
     546                        if (timeToFull != -1) 
     547                            /* 0...1000 */ 
     548                            *pu32PresentRate = (uint32_t)roundf((100.0-(float)remCapacity) / ((float)timeToFull/60.0)) * 10.0; 
     549                    } 
     550                } 
     551 
     552                /* Check for critical */ 
     553                int criticalValue = 20; 
     554                result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSDeadWarnLevelKey), &psValue); 
     555                if (result) 
     556                    CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &criticalValue); 
     557                if (remCapacity < criticalValue) 
     558                    *penmBatteryState = (PDMACPIBATSTATE)(*penmBatteryState | PDM_ACPI_BAT_STATE_CRITICAL); 
     559            } 
     560        } 
     561    } 
     562    CFRelease(pBlob); 
     563    CFRelease(pSources); 
     564#endif /* RT_OS_DARWIN */ 
    416565    return VINF_SUCCESS; 
    417566} 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy