Example #1
0
static double getBatData() {
   CFTypeRef sourceInfo = IOPSCopyPowerSourcesInfo();
   CFArrayRef sourceList = IOPSCopyPowerSourcesList(sourceInfo);

   // Loop through sources, find the first battery
   int count = CFArrayGetCount(sourceList);
   CFDictionaryRef source = NULL;
   for(int i=0; i < count; i++) {
      source = IOPSGetPowerSourceDescription(sourceInfo, CFArrayGetValueAtIndex(sourceList, i));

      // Is this a battery?
      CFStringRef type = (CFStringRef)CFDictionaryGetValue(source, CFSTR(kIOPSTransportTypeKey));
      if(kCFCompareEqualTo == CFStringCompare(type, CFSTR(kIOPSInternalType), 0)) {
         break;
      }
   }

   float percent = 0;
   if(source != NULL) {
      int curCapacity;
      CFNumberGetValue(CFDictionaryGetValue(source, CFSTR(kIOPSCurrentCapacityKey)), kCFNumberIntType, &curCapacity);

      int maxCapacity;
      CFNumberGetValue(CFDictionaryGetValue(source, CFSTR(kIOPSMaxCapacityKey)), kCFNumberIntType, &maxCapacity);

      percent = curCapacity / (float)maxCapacity*100.f;
   }

   CFRelease(sourceInfo);
   CFRelease(sourceList);
   return percent;
}
Example #2
0
/*! Copy the current power dictionary.
 *
 * Caller must release power dictionary when finished with it.
 */
static CFDictionaryRef copy_power_dictionary(CFTypeRef power_key)
{
	CFTypeRef power_blob;
	CFDictionaryRef power_dictionary;

	power_blob = IOPSCopyPowerSourcesInfo();

	assert(power_blob);
	upsdebugx(6, "%s: Got power_blob:", __func__);
	if(nut_debug_level >= 6) CFShow(power_blob);

	upsdebugx(5, "power_key = ");
	if(nut_debug_level >= 5) CFShow(power_key);
	upsdebugx(6, "end power_key");

	power_dictionary = IOPSGetPowerSourceDescription(power_blob, power_key);

	upsdebugx(5, "Asserting 'power_dictionary': %p", power_dictionary);
	assert(power_dictionary);
	upsdebugx(5, "CFShowing 'power_dictionary'");
	if(nut_debug_level >= 5) CFShow(power_dictionary);

	CFRetain(power_dictionary);

	/* Get a new power_blob next time: */
	CFRelease(power_blob);

	return power_dictionary;
}
Example #3
0
int getPowerSource (void)		// returns one of the three #defines above
{
	int result = POWER_SOURCE_ERROR;
	
	CFTypeRef info = NULL;
	CFArrayRef powerSources = NULL;
	CFTypeRef source = NULL;
	CFDictionaryRef description = NULL;
	CFStringRef powerSourceState = NULL;
	
	info = IOPSCopyPowerSourcesInfo();
	if (! info) goto ret;
	powerSources = IOPSCopyPowerSourcesList(info);
	if (! powerSources) goto ret;
	if (CFArrayGetCount(powerSources) == 0) goto ret;
	source = CFArrayGetValueAtIndex(powerSources, 0);
	if (! source) goto ret;
	description = IOPSGetPowerSourceDescription(info, source);
	if (! description) goto ret;
	powerSourceState = CFDictionaryGetValue(description, CFSTR(kIOPSPowerSourceStateKey));
	if (! powerSourceState) goto ret;
	result = (CFStringCompare(powerSourceState, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) ?
		POWER_SOURCE_AC : POWER_SOURCE_BATTERY;
ret :
	if (info) CFRelease (info);
	if (powerSources) CFRelease (powerSources);
	//if (source) CFRelease (source);
	//if (description) CFRelease (description);
	//if (powerSourceState) CFRelease (powerSourceState);
	return result;
}
Example #4
0
static ACPresence chkIsOnline() {
   CFTypeRef sourceInfo = IOPSCopyPowerSourcesInfo();
   CFArrayRef sourceList = IOPSCopyPowerSourcesList(sourceInfo);

   // Loop through sources, find the first battery
   int count = CFArrayGetCount(sourceList);
   CFDictionaryRef source = NULL;
   for(int i=0; i < count; i++) {
      source = IOPSGetPowerSourceDescription(sourceInfo, CFArrayGetValueAtIndex(sourceList, i));

      // Is this a battery?
      CFStringRef type = (CFStringRef)CFDictionaryGetValue(source, CFSTR(kIOPSTransportTypeKey));
      if(kCFCompareEqualTo == CFStringCompare(type, CFSTR(kIOPSInternalType), 0)) {
         break;
      }
   }

   ACPresence isOn = AC_ERROR;
   if(source != NULL) {
      CFStringRef state = CFDictionaryGetValue(source, CFSTR(kIOPSPowerSourceStateKey));
      if(kCFCompareEqualTo == CFStringCompare(state, CFSTR(kIOPSACPowerValue), 0)) {
         isOn = AC_PRESENT;
      } else {
         isOn = AC_ABSENT;
      }
   }

   CFRelease(sourceInfo);
   CFRelease(sourceList);
   return isOn;
}
Example #5
0
static void get_via_io_power_sources(double *ret_charge, /* {{{ */
                                     double *ret_current, double *ret_voltage) {
  CFTypeRef ps_raw;
  CFArrayRef ps_array;
  int ps_array_len;
  CFDictionaryRef ps_dict;
  CFTypeRef ps_obj;

  double temp_double;

  ps_raw = IOPSCopyPowerSourcesInfo();
  ps_array = IOPSCopyPowerSourcesList(ps_raw);
  ps_array_len = CFArrayGetCount(ps_array);

  DEBUG("ps_array_len == %i", ps_array_len);

  for (int i = 0; i < ps_array_len; i++) {
    ps_obj = CFArrayGetValueAtIndex(ps_array, i);
    ps_dict = IOPSGetPowerSourceDescription(ps_raw, ps_obj);

    if (ps_dict == NULL) {
      DEBUG("IOPSGetPowerSourceDescription failed.");
      continue;
    }

    if (CFGetTypeID(ps_dict) != CFDictionaryGetTypeID()) {
      DEBUG("IOPSGetPowerSourceDescription did not return a CFDictionaryRef");
      continue;
    }

    /* FIXME: Check if this is really an internal battery */

    if (isnan(*ret_charge)) {
      /* This is the charge in percent. */
      temp_double = dict_get_double(ps_dict, kIOPSCurrentCapacityKey);
      if (!isnan((temp_double)) && (temp_double >= 0.0) &&
          (temp_double <= 100.0))
        *ret_charge = temp_double;
    }

    if (isnan(*ret_current)) {
      temp_double = dict_get_double(ps_dict, kIOPSCurrentKey);
      if (!isnan(temp_double))
        *ret_current = temp_double / 1000.0;
    }

    if (isnan(*ret_voltage)) {
      temp_double = dict_get_double(ps_dict, kIOPSVoltageKey);
      if (!isnan(temp_double))
        *ret_voltage = temp_double / 1000.0;
    }
  }

  CFRelease(ps_array);
  CFRelease(ps_raw);
} /* }}} void get_via_io_power_sources */
Example #6
0
void CCocoaPowerSyscall::OSPowerSourceCallBack(void *refcon)
{
#if !defined(TARGET_DARWIN_IOS)
  // Called whenever any power source is added, removed, or changes. 
  // When on battery, we get called periodically as battery level changes.
  CCocoaAutoPool autopool;
  CCocoaPowerSyscall  *ctx = (CCocoaPowerSyscall*)refcon;

  CFTypeRef power_sources_info = IOPSCopyPowerSourcesInfo();
  CFArrayRef power_sources_list = IOPSCopyPowerSourcesList(power_sources_info);

  for (int i = 0; i < CFArrayGetCount(power_sources_list); i++)
  {
		CFTypeRef power_source;
		CFDictionaryRef description;

		power_source = CFArrayGetValueAtIndex(power_sources_list, i);
		description  = IOPSGetPowerSourceDescription(power_sources_info, power_source);

    // skip power sources that are not present (i.e. an absent second battery in a 2-battery machine)
    if ((CFBooleanRef)CFDictionaryGetValue(description, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse)
      continue;

    if (stringsAreEqual((CFStringRef)CFDictionaryGetValue(description, CFSTR (kIOPSTransportTypeKey)), CFSTR (kIOPSInternalType))) 
    {
      CFStringRef currentState = (CFStringRef)CFDictionaryGetValue(description, CFSTR (kIOPSPowerSourceStateKey));

      if (stringsAreEqual (currentState, CFSTR (kIOPSACPowerValue)))
      {
        ctx->m_OnBattery = false;
        ctx->m_BatteryPercent = 100;
        ctx->m_SentBatteryMessage = false;
      }
      else if (stringsAreEqual (currentState, CFSTR (kIOPSBatteryPowerValue)))
      {
        CFNumberRef cf_number_ref;
        int32_t curCapacity, maxCapacity;

        cf_number_ref = (CFNumberRef)CFDictionaryGetValue(description, CFSTR(kIOPSCurrentCapacityKey));
        CFNumberGetValue(cf_number_ref, kCFNumberSInt32Type, &curCapacity);

        cf_number_ref = (CFNumberRef)CFDictionaryGetValue(description, CFSTR(kIOPSMaxCapacityKey));
        CFNumberGetValue(cf_number_ref, kCFNumberSInt32Type, &maxCapacity);

        ctx->m_OnBattery = true;
        ctx->m_BatteryPercent = (int)((double)curCapacity/(double)maxCapacity * 100);
      }
		} 
  }

  CFRelease(power_sources_list);
  CFRelease(power_sources_info);
#endif
}
Example #7
0
SDL_bool
SDL_GetPowerInfo_MacOSX(SDL_PowerState * state, int *seconds, int *percent)
{
    CFTypeRef blob = IOPSCopyPowerSourcesInfo();

    *seconds = -1;
    *percent = -1;
    *state = SDL_POWERSTATE_UNKNOWN;

    if (blob != NULL) {
        CFArrayRef list = IOPSCopyPowerSourcesList(blob);
        if (list != NULL) {
            /* don't CFRelease() the list items, or dictionaries! */
            SDL_bool have_ac = SDL_FALSE;
            SDL_bool have_battery = SDL_FALSE;
            SDL_bool charging = SDL_FALSE;
            const CFIndex total = CFArrayGetCount(list);
            CFIndex i;
            for (i = 0; i < total; i++) {
                CFTypeRef ps = (CFTypeRef) CFArrayGetValueAtIndex(list, i);
                CFDictionaryRef dict =
                    IOPSGetPowerSourceDescription(blob, ps);
                if (dict != NULL) {
                    checkps(dict, &have_ac, &have_battery, &charging,
                            seconds, percent);
                }
            }

            if (!have_battery) {
                *state = SDL_POWERSTATE_NO_BATTERY;
            } else if (charging) {
                *state = SDL_POWERSTATE_CHARGING;
            } else if (have_ac) {
                *state = SDL_POWERSTATE_CHARGED;
            } else {
                *state = SDL_POWERSTATE_ON_BATTERY;
            }

            CFRelease(list);
        }
        CFRelease(blob);
    }

    return SDL_TRUE;            /* always the definitive answer on Mac OS X. */
}
Example #8
0
//  CODE CHUNK IMPORTED FROM SDL 2.0
bool power_osx::GetPowerInfo_MacOSX() {
	CFTypeRef blob = IOPSCopyPowerSourcesInfo();

	nsecs_left = -1;
	percent_left = -1;
	power_state = OS::POWERSTATE_UNKNOWN;

	if (blob != NULL) {
		CFArrayRef list = IOPSCopyPowerSourcesList(blob);
		if (list != NULL) {
			/* don't CFRelease() the list items, or dictionaries! */
			bool have_ac = false;
			bool have_battery = false;
			bool charging = false;
			const CFIndex total = CFArrayGetCount(list);
			CFIndex i;
			for (i = 0; i < total; i++) {
				CFTypeRef ps = (CFTypeRef)CFArrayGetValueAtIndex(list, i);
				CFDictionaryRef dict = IOPSGetPowerSourceDescription(blob, ps);
				if (dict != NULL) {
					checkps(dict, &have_ac, &have_battery, &charging);
				}
			}

			if (!have_battery) {
				power_state = OS::POWERSTATE_NO_BATTERY;
			} else if (charging) {
				power_state = OS::POWERSTATE_CHARGING;
			} else if (have_ac) {
				power_state = OS::POWERSTATE_CHARGED;
			} else {
				power_state = OS::POWERSTATE_ON_BATTERY;
			}

			CFRelease(list);
		}
		CFRelease(blob);
	}

	return true; /* always the definitive answer on Mac OS X. */
}
/* IOPSCopyUPSArray
 *
 * Argument: 
 *	CFTypeRef power_sources: The return value from IOPSCoyPowerSourcesInfo()
 * Return value:
 * 	CFArrayRef: all the UPS's we found
 *			NULL if none are found
 */
 CFArrayRef
IOPSCopyUPSArray(CFTypeRef power_sources)
{
    CFArrayRef			array = isA_CFArray(IOPSCopyPowerSourcesList(power_sources));
    CFMutableArrayRef   ret_arr;
    CFTypeRef			name = NULL;
    CFDictionaryRef		ps;
    CFStringRef			transport_type;
    int				    i, count;

    if(!array) return NULL;
    count = CFArrayGetCount(array);
    name = NULL;

    ret_arr = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    if(!ret_arr) goto exit;

    // Iterate through power_sources
    for(i=0; i<count; i++) {
        name = CFArrayGetValueAtIndex(array, i);
        ps = isA_CFDictionary(IOPSGetPowerSourceDescription(power_sources, name));
        if(ps) {
            transport_type = isA_CFString(CFDictionaryGetValue(ps, CFSTR(kIOPSTransportTypeKey)));
            if(transport_type && ( CFEqual(transport_type, CFSTR(kIOPSSerialTransportType)) ||
                CFEqual(transport_type, CFSTR(kIOPSUSBTransportType)) ||
                CFEqual(transport_type, CFSTR(kIOPSNetworkTransportType)) ) )
            {
                CFArrayAppendValue(ret_arr, name);
            }
        }
    }

    if(0 == CFArrayGetCount(ret_arr)) {
        CFRelease(ret_arr);
        ret_arr = NULL;
    }

exit:
    CFRelease(array);
    return ret_arr;
}
Example #10
0
bool CScreensaver::Host_is_running_on_batteries() {
    CFDictionaryRef pSource = NULL;
    CFStringRef psState;
    int i;
    bool retval = false;

    CFTypeRef blob = IOPSCopyPowerSourcesInfo();
    CFArrayRef list = IOPSCopyPowerSourcesList(blob);

    for (i=0; i<CFArrayGetCount(list); i++) {
        pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(list, i));
        if(!pSource) break;
        psState = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSPowerSourceStateKey));
        if(!CFStringCompare(psState,CFSTR(kIOPSBatteryPowerValue),0))
        retval = true;
    }

    CFRelease(blob);
    CFRelease(list);
        
    return retval;
}
/* PSLowPowerPSChange
 *
 * Is the handler that gets notified when power source (battery or UPS)
 * state changes. We might respond to this by posting a user notification
 * or performing emergency shutdown.
 */
__private_extern__ void
PSLowPowerPSChange(CFTypeRef ps_blob) 
{
    CFTypeRef           ups = NULL;
    CFDictionaryRef     ups_info = 0;
    int                 t1, t2;
    CFNumberRef         n1, n2;
    int                 minutes_remaining;
    int                 percent_remaining;
    CFBooleanRef        isPresent;
    static int          last_ups_power_source = _kIOUPSExternalPowerBit;
    CFStringRef         power_source = 0;
    CFNumberRef         ups_id = 0;
    
    // Bail immediately if another application (like APC's PowerChute) 
    //   is managing emergency UPS shutdown
    if(!_weManageUPSPower()) {
        goto _exit_PowerSourcesHaveChanged_;
    }
    
    // *** Inspect UPS power levels
    // We assume we're only dealing with 1 UPS for simplicity.
    // The "more than one UPS attached " case is undefined.
    if((ups = IOPSGetActiveUPS(ps_blob)))
    {
        ups_info = isA_CFDictionary(IOPSGetPowerSourceDescription(ps_blob, ups));
        if(!ups_info) goto _exit_PowerSourcesHaveChanged_;

        ups_id = isA_CFNumber(CFDictionaryGetValue(ups_info, CFSTR(kIOPSPowerSourceIDKey)));
        if(!ups_id) goto _exit_PowerSourcesHaveChanged_;
        
        // Check UPS "Is Present" key
        isPresent = isA_CFBoolean(CFDictionaryGetValue(ups_info, CFSTR(kIOPSIsPresentKey)));
        if(!isPresent || !CFBooleanGetValue(isPresent))
        {
#if HAVE_CF_USER_NOTIFICATION
            if(_UPSAlert)
            {
                CFUserNotificationCancel(_UPSAlert);
                _UPSAlert = 0;
            }
#endif
            // If UPS isn't active or connected we shouldn't base policy decisions on it
            goto _exit_PowerSourcesHaveChanged_;
        }
        
        // Check Power Source
        power_source = isA_CFString(CFDictionaryGetValue(ups_info, CFSTR(kIOPSPowerSourceStateKey)));
        if(!power_source || !CFEqual(power_source, CFSTR(kIOPSBatteryPowerValue)))
        {
#if HAVE_CF_USER_NOTIFICATION
            // Running off of AC Power
            if(_UPSAlert)
            {
                CFUserNotificationCancel(_UPSAlert);
                _UPSAlert = 0;
            }
#endif                
            // we have to be draining the internal battery to do a shutdown, so we'll just exit from here.
            goto _exit_PowerSourcesHaveChanged_;
        }
        
        // UPS is running off of internal battery power. Show warning if we just switched from AC to battery.
        if(_kIOUPSExternalPowerBit == last_ups_power_source)
        {
            _switchedToUPSPowerTime = CFAbsoluteTimeGetCurrent();
            
            if( _thresh->haltafter[kHaltEnabled] ) {    
                // If there's a "shutdown after X minutes on UPS power" threshold, 
                // set a timer to remind us to check UPS state again after X minutes
                _reEvaluatePowerSourcesLater(5 + (60*_thresh->haltafter[kHaltValue]));
            }
            
#if HAVE_CF_USER_NOTIFICATION
            if(!_UPSAlert) _UPSAlert = _copyUPSWarning();
#endif 

        }
        
        // TODO: switch this battery-present check for the IOKit 
        //       private API IOPMSystemSupportsUPSShutdown
        // Is an internal battery present?
        if(kCFBooleanTrue == IOPSPowerSourceSupported(ps_blob, CFSTR(kIOPMBatteryPowerKey)))
        {
            // Do not do UPS shutdown if internal battery is present.
            // Internal battery may still be providing power. 
            // Don't do any further UPS shutdown processing.
            // PMU will cause an emergency sleep when the battery runs out - we fall back on that
            // in the battery case.
            goto _exit_PowerSourcesHaveChanged_;                
        }
        
        // ******
        // ****** Perform emergency shutdown if any of the shutdown thresholds is true
        
        // Check to make sure that the UPS has been on battery power for a full 10 seconds before initiating a shutdown.
        // Certain UPS's have reported transient "on battery power with 0% capacity remaining" states for 3-5 seconds.
        // So we make sure not to heed this shutdown notice unless we've been on battery power for 10 seconds.
        if(_secondsSpentOnUPSPower() < 10) {
            _reEvaluatePowerSourcesLater(10);
            goto _exit_PowerSourcesHaveChanged_;
         }
        
        // Calculate battery percentage remaining
        n1 = isA_CFNumber(CFDictionaryGetValue(ups_info, CFSTR(kIOPSCurrentCapacityKey)));
        n2 = isA_CFNumber(CFDictionaryGetValue(ups_info, CFSTR(kIOPSMaxCapacityKey)));
        if(n1 && n2)
        {
            if( CFNumberGetValue(n1, kCFNumberIntType, &t1) &&
                CFNumberGetValue(n2, kCFNumberIntType, &t2)) {
                percent_remaining = (int)(100.0* ((double)t1) / ((double)t2) );
    
                if( _thresh->haltpercent[kHaltEnabled] ) {
                    if( percent_remaining <= _thresh->haltpercent[kHaltValue] ) {
                        _doPowerEmergencyShutdown(ups_id);
                    }
                }
            }
        }
        
        // Get UPS's estimated time remaining
        n1 = isA_CFNumber(CFDictionaryGetValue(ups_info, CFSTR(kIOPSTimeToEmptyKey)));
        if(n1)
        {
            if(CFNumberGetValue(n1, kCFNumberIntType, &minutes_remaining))
            {
                if( _thresh->haltremain[kHaltEnabled] ) {
                    if( minutes_remaining <= _thresh->haltremain[kHaltValue] ) {
                        _doPowerEmergencyShutdown(ups_id);
                    }
                }
            }
        }

        // Determine how long we've been running on UPS power
        if( _thresh->haltafter[kHaltEnabled] ) {
            if(_minutesSpentOnUPSPower() >= _thresh->haltafter[kHaltValue]) {
                _doPowerEmergencyShutdown(ups_id);
            }
        }
        
    } else {
        // No "active UPS" detected. 
        // One could have just disappeared - if we're showing an alert, clear it.
#if HAVE_CF_USER_NOTIFICATION
        if(_UPSAlert)
        {
            CFUserNotificationCancel(_UPSAlert);
            _UPSAlert = 0;
        }
#endif
    }
    
    // exit point
    _exit_PowerSourcesHaveChanged_:
    
    if(power_source && CFEqual(power_source, CFSTR(kIOPSBatteryPowerValue))) {
        last_ups_power_source = _kIOUPSInternalPowerBit;
    } else {
        last_ups_power_source = _kIOUPSExternalPowerBit;
    }
    
    return;
}
Example #12
0
PowerInfo GetPowerState()
{
    PowerInfo info;

    info.state = PowerInfo::STATE_UNKNOWN;
    info.seconds = 0;
    info.percent = 0.0f;


    #if defined(TARGET_OSX)

    CFTypeRef blob = IOPSCopyPowerSourcesInfo();

    if (blob != NULL)
    {
        CFArrayRef list = IOPSCopyPowerSourcesList(blob);
        if (list != NULL) {
            /* don't CFRelease() the list items, or dictionaries! */
            bool have_ac = false;
            bool have_battery = false;
            bool charging = false;
            const CFIndex total = CFArrayGetCount(list);
            CFIndex i;
            for (i = 0; i < total; i++)
            {
                CFTypeRef ps = (CFTypeRef) CFArrayGetValueAtIndex(list, i);
                CFDictionaryRef dict =
                    IOPSGetPowerSourceDescription(blob, ps);
                if (dict != NULL)
                {
                    checkps(dict,
                            &have_ac,
                            &have_battery,
                            &charging,
                            &info.seconds,
                            &info.percent);
                }
            }

            if (!have_battery)
            {
                info.state = PowerInfo::STATE_NO_BATTERY;
            }
            else if (charging)
            {
                info.state = PowerInfo::STATE_CHARGING;
            }
            else if (have_ac)
            {
                info.state = PowerInfo::STATE_CHARGED;
            }
            else
            {
                info.state = PowerInfo::STATE_ON_BATTERY;
            }

            CFRelease(list);
        }
        CFRelease(blob);
    }

    #elif defined(TARGET_LINUX)

    #else

    #endif


    return info;
}
Example #13
0
int OnBattery (void)
{
#if defined (__APPLE__)
/* The following copyright applies to the battery detection code below.  I did modify */
/* substantially as it did far more than I needed. */

/* Copyright (c) 2003 Thomas Runge ([email protected])
 * Mach and Darwin specific code is Copyright (c) 2006 Eric Pooch ([email protected])
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
	CFTypeRef blob = IOPSCopyPowerSourcesInfo();
	CFArrayRef sources = IOPSCopyPowerSourcesList(blob);

	int i, acstat;
	CFDictionaryRef pSource = NULL;
	const void *psValue;

	acstat = TRUE;

	for(i = 0; i < CFArrayGetCount(sources); i++)
	{
		pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));
		if(!pSource) break;

		psValue = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey));

		if (CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsPresentKey), &psValue) && (CFBooleanGetValue(psValue) > 0))
		{
			psValue = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSPowerSourceStateKey));

			if (CFStringCompare(psValue,CFSTR(kIOPSBatteryPowerValue),0)==kCFCompareEqualTo)
			{
				/* We are running on a battery power source. */
				acstat = FALSE;
			}
		}
	}

	CFRelease(blob);
	CFRelease(sources);

	return(!acstat);
#elif defined (__linux__)
	FILE	*fd;
	char	buf[180];
	int	ac_state;

	ac_state = -1;
	fd = fopen ("/proc/acpi/battery/BAT0/state", "r");
	if (fd != NULL) {
		while (fgets (buf, sizeof (buf), fd) != NULL) {
			char	*p;
			p = strstr (buf, "charging state:");
			if (p == NULL) continue;
			if (strstr (p+14, "discharging") != NULL) ac_state = 0;
			else if (strstr (p+14, "charging") != NULL) ac_state = 1;
			else if (strstr (p+14, "charged") != NULL) ac_state = 1;
		}
		fclose (fd);
	}
	return (ac_state == 0);
#else
	return (FALSE);		/* Assume we're on AC power */
#endif
}
int
machine_get_battstat(int *acstat, int *battflag, int *percent)
{
	CFTypeRef blob = IOPSCopyPowerSourcesInfo();
	CFArrayRef sources = IOPSCopyPowerSourcesList(blob);

	int i;
	CFDictionaryRef pSource = NULL;
	const void *psValue;

	*acstat = LCDP_AC_ON;
	*battflag = LCDP_BATT_ABSENT;
	*percent = 100;

	if (CFArrayGetCount(sources) == 0)
		return (FALSE);

	for (i = 0; i < CFArrayGetCount(sources); i++) {
		pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));
		if (!pSource)
			break;

		psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey));

		if (CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsPresentKey), &psValue) && (CFBooleanGetValue(psValue) > 0)) {
			psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSPowerSourceStateKey));

			if (CFStringCompare(psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) {
				/* We are running on a battery power source. */
				*battflag = LCDP_BATT_UNKNOWN;
				*acstat = LCDP_AC_OFF;
			}
			else if (CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsChargingKey), &psValue)) {
				/*
				 * We are running on an AC power source, but
				 * we also have a battery power source
				 * present.
				 */

				if (CFBooleanGetValue(psValue) > 0)
					*battflag = LCDP_BATT_CHARGING;
				else
					*battflag = LCDP_BATT_UNKNOWN;
			}

			if (*battflag != LCDP_BATT_ABSENT) {
				int curCapacity = 0;
				int maxCapacity = 0;

				psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey));
				CFNumberGetValue(psValue, kCFNumberSInt32Type, &curCapacity);

				psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey));
				CFNumberGetValue(psValue, kCFNumberSInt32Type, &maxCapacity);

				*percent = (int)((double)curCapacity / (double)maxCapacity * 100);

				/*
				 * There is a way to check this through the
				 * IOKit, but I am not sure what gets
				 * returned for kIOPSLowWarnLevelKey and
				 * kIOPSDeadWarnLevelKey, and this is easier.
				 */
				if (*battflag == LCDP_BATT_UNKNOWN) {
					if (*percent > 50)
						*battflag = LCDP_BATT_HIGH;
					else if (*percent > 2)
						*battflag = LCDP_BATT_LOW;
					else
						*battflag = LCDP_BATT_CRITICAL;
				}
				/* printf ("powerSource %d of %d: percent: %d/%d %d\n", i, CFArrayGetCount(sources), curCapacity, maxCapacity, *percent);*/
			}
		}
	}

	CFRelease(blob);
	CFRelease(sources);

	return (TRUE);
}
Example #15
0
static void
darwin_check(void)
{
   const void *values;
   int device_num, device_count;
   int currentval = 0, maxval = 0;
   char buf[4096];
   CFTypeRef blob;
   CFArrayRef sources;
   CFDictionaryRef device_dict;

   time_left = -1;
   battery_full = -1;
   have_battery = 0;
   have_power = 0;

   /* Retrieve the power source data and the array of sources. */
   blob = IOPSCopyPowerSourcesInfo();
   sources = IOPSCopyPowerSourcesList(blob);
   device_count = CFArrayGetCount(sources);
   for (device_num = 0; device_num < device_count; device_num++)
     {
        CFTypeRef ps;

        /* Retrieve a dictionary of values for this device and the count of keys in the dictionary. */
        ps = CFArrayGetValueAtIndex(sources, device_num);
        device_dict = IOPSGetPowerSourceDescription(blob, ps);
        /* Retrieve the charging key and save the present charging value if one exists. */
        if (CFDictionaryGetValueIfPresent(device_dict,
                                          CFSTR(kIOPSIsChargingKey), &values))
          {
             have_battery = 1;
             if (CFBooleanGetValue(values) > 0) have_power = 1;
             break;
          }
     }

   if (!have_battery)
     {
        CFRelease(sources);
        CFRelease(blob);
        have_power = 1;
        return;
     }

   /* Retrieve the current capacity key. */
   values = CFDictionaryGetValue(device_dict, CFSTR(kIOPSCurrentCapacityKey));
   CFNumberGetValue(values, kCFNumberSInt32Type, &currentval);
   /* Retrieve the max capacity key. */
   values = CFDictionaryGetValue(device_dict, CFSTR(kIOPSMaxCapacityKey));
   CFNumberGetValue(values, kCFNumberSInt32Type, &maxval);
   /* Calculate the percentage charged. */
   battery_full = (currentval * 100) / maxval;

   /* Retrieve the remaining battery power or time until charged in minutes. */
   if (!have_power)
     {
        values = CFDictionaryGetValue(device_dict, CFSTR(kIOPSTimeToEmptyKey));
        CFNumberGetValue(values, kCFNumberSInt32Type, &currentval);
        time_left = currentval * 60;
     }
   else
     {
        values = CFDictionaryGetValue(device_dict, CFSTR(kIOPSTimeToFullChargeKey));
        CFNumberGetValue(values, kCFNumberSInt32Type, &currentval);
        time_left = currentval * 60;
     }
   CFRelease(sources);
   CFRelease(blob);
}
Example #16
0
void HostPowerServiceDarwin::checkBatteryCriticalLevel(bool *pfCriticalChanged)
{
    CFTypeRef pBlob = IOPSCopyPowerSourcesInfo();
    CFArrayRef pSources = IOPSCopyPowerSourcesList(pBlob);

    CFDictionaryRef pSource = NULL;
    const void *psValue;
    bool result;
    int powerSource = POWER_SOURCE_OUTLET;
    bool critical = false;

    if (CFArrayGetCount(pSources) > 0)
    {
        for (int i = 0; i < CFArrayGetCount(pSources); ++i)
        {
            pSource = IOPSGetPowerSourceDescription(pBlob, CFArrayGetValueAtIndex(pSources, i));
            /* If the source is empty skip over to the next one. */
            if (!pSource)
                continue;
            /* Skip all power sources which are currently not present like a
             * second battery. */
            if (CFDictionaryGetValue(pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse)
                continue;
            /* Only internal power types are of interest. */
            result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTransportTypeKey), &psValue);
            if (result &&
                CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo)
            {
                /* First check which power source we are connect on. */
                result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue);
                if (result &&
                    CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo)
                    powerSource = POWER_SOURCE_OUTLET;
                else if (result &&
                         CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo)
                    powerSource = POWER_SOURCE_BATTERY;

                int curCapacity = 0;
                int maxCapacity = 1;
                float remCapacity = 0.0f;

                /* Fetch the current capacity value of the power source */
                result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSCurrentCapacityKey), &psValue);
                if (result)
                    CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity);
                /* Fetch the maximum capacity value of the power source */
                result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSMaxCapacityKey), &psValue);
                if (result)
                    CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity);

                /* Calculate the remaining capacity in percent */
                remCapacity = ((float)curCapacity/(float)maxCapacity * 100.0);

                /* Check for critical. 5 percent is default. */
                int criticalValue = 5;
                result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSDeadWarnLevelKey), &psValue);
                if (result)
                    CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &criticalValue);
                critical = (remCapacity < criticalValue);
                /* We have to take action only if we are on battery, the
                 * previous state wasn't critical, the state has changed & the
                 * user requested that info. */
                if (powerSource == POWER_SOURCE_BATTERY &&
                    mCritical == false &&
                    mCritical != critical &&
                    pfCriticalChanged)
                    *pfCriticalChanged = true;
                Log(("checkBatteryCriticalLevel: Remains: %d.%d%% Critical: %d Critical State Changed: %d\n", (int)remCapacity, (int)(remCapacity * 10) % 10, critical, pfCriticalChanged?*pfCriticalChanged:-1));
            }
        }
    }
    /* Save the new state */
    mCritical = critical;

    CFRelease(pBlob);
    CFRelease(pSources);
}
Example #17
0
static void powerSourceChanged(void *context)
{
#pragma unused(context)
	CFTypeRef	powerBlob = IOPSCopyPowerSourcesInfo();
	CFArrayRef	powerSourcesList = IOPSCopyPowerSourcesList(powerBlob);

	CFIndex	count = CFArrayGetCount(powerSourcesList);
	for (CFIndex i = 0; i < count; ++i) {
		CFTypeRef		powerSource;
		CFDictionaryRef description;

		HGPowerSource	hgPowerSource;
		CFBooleanRef	charging = kCFBooleanFalse;
		CFIndex			batteryTime = -1;
		CFIndex			percentageCapacity = -1;

		powerSource = CFArrayGetValueAtIndex(powerSourcesList, i);
		description = IOPSGetPowerSourceDescription(powerBlob, powerSource);

		//Don't display anything for power sources that aren't present (i.e. an absent second battery in a 2-battery machine)
		if (CFDictionaryGetValue(description, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse)
			continue;

		//We only know how to handle internal (battery, a/c power) transport types. The other values indicate UPS usage.
		if (stringsAreEqual(CFDictionaryGetValue(description, CFSTR(kIOPSTransportTypeKey)),
							CFSTR(kIOPSInternalType))) {
			CFStringRef currentState = CFDictionaryGetValue(description, CFSTR(kIOPSPowerSourceStateKey));
			if (stringsAreEqual(currentState, CFSTR(kIOPSACPowerValue)))
				hgPowerSource = HGACPower;
			else if (stringsAreEqual(currentState, CFSTR(kIOPSBatteryPowerValue)))
				hgPowerSource = HGBatteryPower;
			else
				hgPowerSource = HGUnknownPower;

			//Battery power
			if (CFDictionaryGetValue(description, CFSTR(kIOPSIsChargingKey)) == kCFBooleanTrue) {
				//Charging
				charging = kCFBooleanTrue;

				CFNumberRef timeToChargeNum = CFDictionaryGetValue(description, CFSTR(kIOPSTimeToFullChargeKey));
				CFIndex timeToCharge;

				if (CFNumberGetValue(timeToChargeNum, kCFNumberCFIndexType, &timeToCharge))
					batteryTime = timeToCharge;
			} else {
				//Not charging
				charging = kCFBooleanFalse;

				CFNumberRef timeToEmptyNum = CFDictionaryGetValue(description, CFSTR(kIOPSTimeToEmptyKey));
				CFIndex timeToEmpty;

				if (CFNumberGetValue(timeToEmptyNum, kCFNumberCFIndexType, &timeToEmpty))
					batteryTime = timeToEmpty;
			}

			/* Capacity */
			CFNumberRef currentCapacityNum = CFDictionaryGetValue(description, CFSTR(kIOPSCurrentCapacityKey));
			CFNumberRef maxCapacityNum = CFDictionaryGetValue(description, CFSTR(kIOPSMaxCapacityKey));

			CFIndex currentCapacity, maxCapacity;

			if (CFNumberGetValue(currentCapacityNum, kCFNumberCFIndexType, &currentCapacity) &&
					CFNumberGetValue(maxCapacityNum, kCFNumberCFIndexType, &maxCapacity))
				percentageCapacity = roundf((currentCapacity / (float)maxCapacity) * 100.0f);

		} else {
			//UPS power
			hgPowerSource = HGUPSPower;
		}

		//Avoid sending notifications on the same power source multiple times, unless the charging state or presence/absence of a time estimate has changed.
		if (lastPowerSource != hgPowerSource || lastChargingState != charging || (lastBatteryTime == -1) != (batteryTime == -1)) {
			lastPowerSource = hgPowerSource;
			lastChargingState = charging;
			lastBatteryTime = batteryTime;
			AppController_powerSwitched(hgPowerSource, charging, batteryTime, percentageCapacity);
		}
	}

	CFRelease(powerSourcesList);
	CFRelease(powerBlob);
}