diff options
author | Benny Baumann <BenBE@geshi.org> | 2021-07-29 23:53:58 +0200 |
---|---|---|
committer | Daniel Lange <DLange@git.local> | 2021-08-02 14:37:44 +0200 |
commit | e341217fea844e1c45b7079146b9de7cb68e8c2a (patch) | |
tree | b38202f1319019df4c16a8bc4b94bd35bc8bafe9 /darwin | |
parent | 44e01dd32b417ff0118cfa6183f31032966a93c1 (diff) |
Properly handle multiple batteries on darwin
This makes the behaviour consistent with other platforms where AC is
marked as present if at least one power source is marked as AC_PRESENT.
Fixes: #711
Diffstat (limited to 'darwin')
-rw-r--r-- | darwin/Platform.c | 80 |
1 files changed, 35 insertions, 45 deletions
diff --git a/darwin/Platform.c b/darwin/Platform.c index 3fcf314d..df7e133f 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -347,67 +347,57 @@ bool Platform_getNetworkIO(NetworkIOData* data) { } void Platform_getBattery(double* percent, ACPresence* isOnAC) { - CFTypeRef power_sources = IOPSCopyPowerSourcesInfo(); - *percent = NAN; *isOnAC = AC_ERROR; - if (NULL == power_sources) - return; + CFArrayRef list = NULL; - CFArrayRef list = IOPSCopyPowerSourcesList(power_sources); - CFDictionaryRef battery = NULL; - int len; - - if (NULL == list) { - CFRelease(power_sources); + CFTypeRef power_sources = IOPSCopyPowerSourcesInfo(); + if (!power_sources) + goto cleanup; - return; - } + list = IOPSCopyPowerSourcesList(power_sources); + if (!list) + goto cleanup; - len = CFArrayGetCount(list); + double cap_current = 0.0; + double cap_max = 0.0; /* Get the battery */ - for (int i = 0; i < len && battery == NULL; ++i) { - CFDictionaryRef candidate = IOPSGetPowerSourceDescription(power_sources, - CFArrayGetValueAtIndex(list, i)); /* GET rule */ - CFStringRef type; - - if (NULL != candidate) { - type = (CFStringRef) CFDictionaryGetValue(candidate, - CFSTR(kIOPSTransportTypeKey)); /* GET rule */ - - if (kCFCompareEqualTo == CFStringCompare(type, CFSTR(kIOPSInternalType), 0)) { - CFRetain(candidate); - battery = candidate; - } - } - } + for (int i = 0, len = CFArrayGetCount(list); i < len; ++i) { + CFDictionaryRef power_source = IOPSGetPowerSourceDescription(power_sources, CFArrayGetValueAtIndex(list, i)); /* GET rule */ - if (NULL != battery) { - /* Determine the AC state */ - CFStringRef power_state = CFDictionaryGetValue(battery, CFSTR(kIOPSPowerSourceStateKey)); + if (!power_source) + continue; - *isOnAC = (kCFCompareEqualTo == CFStringCompare(power_state, CFSTR(kIOPSACPowerValue), 0)) - ? AC_PRESENT - : AC_ABSENT; + CFStringRef power_type = CFDictionaryGetValue(power_source, CFSTR(kIOPSTransportTypeKey)); /* GET rule */ - /* Get the percentage remaining */ - double current; - double max; + if (kCFCompareEqualTo != CFStringCompare(power_type, CFSTR(kIOPSInternalType), 0)) + continue; - CFNumberGetValue(CFDictionaryGetValue(battery, CFSTR(kIOPSCurrentCapacityKey)), - kCFNumberDoubleType, ¤t); - CFNumberGetValue(CFDictionaryGetValue(battery, CFSTR(kIOPSMaxCapacityKey)), - kCFNumberDoubleType, &max); + /* Determine the AC state */ + CFStringRef power_state = CFDictionaryGetValue(power_source, CFSTR(kIOPSPowerSourceStateKey)); - *percent = (current * 100.0) / max; + if (*isOnAC != AC_PRESENT) + *isOnAC = (kCFCompareEqualTo == CFStringCompare(power_state, CFSTR(kIOPSACPowerValue), 0)) ? AC_PRESENT : AC_ABSENT; - CFRelease(battery); + /* Get the percentage remaining */ + double tmp; + CFNumberGetValue(CFDictionaryGetValue(power_source, CFSTR(kIOPSCurrentCapacityKey)), kCFNumberDoubleType, &tmp); + cap_current += tmp; + CFNumberGetValue(CFDictionaryGetValue(power_source, CFSTR(kIOPSMaxCapacityKey)), kCFNumberDoubleType, &tmp); + cap_max += tmp; } - CFRelease(list); - CFRelease(power_sources); + if (cap_max > 0.0) + *percent = 100.0 * cap_current / cap_max; + +cleanup: + if (list) + CFRelease(list); + + if (power_sources) + CFRelease(power_sources); } void Platform_gettime_monotonic(uint64_t* msec) { |