This is xnu-11215.1.10. See this file in:
/*
* Copyright (c) 1998-2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#include <IOKit/pwr_mgt/IOPMPowerSource.h>
#include <IOKit/pwr_mgt/IOPM.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOLib.h>
#include <os/log.h>
#define super IOService
OSDefineMetaClassAndStructors(IOPMPowerSource, IOService)
// *****************************************************************************
// powerSource
//
// Static initializer for IOPMPowerSource. Returns a new instance of the class
// which the caller must attach to the power plane.
// *****************************************************************************
IOPMPowerSource *IOPMPowerSource::powerSource(void)
{
IOPMPowerSource *ps = new IOPMPowerSource;
if (ps) {
ps->init();
return ps;
}
return NULL;
}
// *****************************************************************************
// init
//
// *****************************************************************************
bool
IOPMPowerSource::init(void)
{
if (!super::init()) {
return false;
}
nextInList = NULL;
properties = OSDictionary::withCapacity(10);
if (!properties) {
return false;
}
properties->setCapacityIncrement(1);
externalConnectedKey = OSSymbol::withCString(kIOPMPSExternalConnectedKey);
externalChargeCapableKey = OSSymbol::withCString(kIOPMPSExternalChargeCapableKey);
batteryInstalledKey = OSSymbol::withCString(kIOPMPSBatteryInstalledKey);
chargingKey = OSSymbol::withCString(kIOPMPSIsChargingKey);
warnLevelKey = OSSymbol::withCString(kIOPMPSAtWarnLevelKey);
criticalLevelKey = OSSymbol::withCString(kIOPMPSAtCriticalLevelKey);
currentCapacityKey = OSSymbol::withCString(kIOPMPSCurrentCapacityKey);
maxCapacityKey = OSSymbol::withCString(kIOPMPSMaxCapacityKey);
timeRemainingKey = OSSymbol::withCString(kIOPMPSTimeRemainingKey);
amperageKey = OSSymbol::withCString(kIOPMPSAmperageKey);
voltageKey = OSSymbol::withCString(kIOPMPSVoltageKey);
cycleCountKey = OSSymbol::withCString(kIOPMPSCycleCountKey);
adapterInfoKey = OSSymbol::withCString(kIOPMPSAdapterInfoKey);
locationKey = OSSymbol::withCString(kIOPMPSLocationKey);
errorConditionKey = OSSymbol::withCString(kIOPMPSErrorConditionKey);
manufacturerKey = OSSymbol::withCString(kIOPMPSManufacturerKey);
modelKey = OSSymbol::withCString(kIOPMPSModelKey);
serialKey = OSSymbol::withCString(kIOPMPSSerialKey);
batteryInfoKey = OSSymbol::withCString(kIOPMPSLegacyBatteryInfoKey);
return true;
}
// *****************************************************************************
// free
//
// *****************************************************************************
void
IOPMPowerSource::free(void)
{
if (properties) {
properties->release();
}
if (externalConnectedKey) {
externalConnectedKey->release();
}
if (externalChargeCapableKey) {
externalChargeCapableKey->release();
}
if (batteryInstalledKey) {
batteryInstalledKey->release();
}
if (chargingKey) {
chargingKey->release();
}
if (warnLevelKey) {
warnLevelKey->release();
}
if (criticalLevelKey) {
criticalLevelKey->release();
}
if (currentCapacityKey) {
currentCapacityKey->release();
}
if (maxCapacityKey) {
maxCapacityKey->release();
}
if (timeRemainingKey) {
timeRemainingKey->release();
}
if (amperageKey) {
amperageKey->release();
}
if (voltageKey) {
voltageKey->release();
}
if (cycleCountKey) {
cycleCountKey->release();
}
if (adapterInfoKey) {
adapterInfoKey->release();
}
if (errorConditionKey) {
errorConditionKey->release();
}
if (manufacturerKey) {
manufacturerKey->release();
}
if (modelKey) {
modelKey->release();
}
if (serialKey) {
serialKey->release();
}
if (locationKey) {
locationKey->release();
}
if (batteryInfoKey) {
batteryInfoKey->release();
}
super::free();
}
// *****************************************************************************
// updateStatus
//
// Update power source state in IORegistry and message interested clients
// notifying them of our change.
// *****************************************************************************
void
IOPMPowerSource::updateStatus(void)
{
OSCollectionIterator *iterator;
OSObject *iteratorKey;
OSObject *obj;
// do nothing if settings haven't changed
if (!settingsChangedSinceUpdate) {
return;
}
iterator = OSCollectionIterator::withCollection(properties);
if (!iterator) {
return;
}
while ((iteratorKey = iterator->getNextObject())) {
OSSymbol *key;
key = OSDynamicCast(OSSymbol, iteratorKey);
if (!key) {
continue;
}
obj = properties->getObject(key);
if (!obj) {
continue;
}
setProperty(key, obj);
}
iterator->release();
settingsChangedSinceUpdate = false;
// And up goes the flare
IOMessage notifyMessage = kIOPMMessageBatteryStatusHasChanged;
#if DEVELOPMENT || DEBUG
os_log(OS_LOG_DEFAULT, "notify clients '%u'\n", (unsigned int)notifyMessage);
#endif
messageClients(notifyMessage);
}
/*******************************************************************************
*
* PROTECTED Accessors. All the setters! Yay!
*
******************************************************************************/
void
IOPMPowerSource::setPSProperty(const OSSymbol *key, OSObject *val)
{
OSObject *lastVal;
if (!key || !val) {
return;
}
// Compare new setting with existing setting; update
// 'settingsChangedSinceUpdate' if the setting has changed.
// If values are OSNumbers, do equality comparison.
// Otherwise, just compare pointers.
if ((lastVal = properties->getObject(key))) {
if (val->isEqualTo(lastVal)) {
// settings didn't change
} else {
// num val is not equal to last val
settingsChangedSinceUpdate = true;
}
} else {
// new setting; no last value
settingsChangedSinceUpdate = true;
}
// here's the part where we go crazy.
properties->setObject(key, val);
}
void
IOPMPowerSource::setExternalConnected(bool b)
{
setPSProperty(externalConnectedKey,
b ? kOSBooleanTrue : kOSBooleanFalse);
}
void
IOPMPowerSource::setExternalChargeCapable(bool b)
{
setPSProperty(externalChargeCapableKey,
b ? kOSBooleanTrue : kOSBooleanFalse);
}
void
IOPMPowerSource::setBatteryInstalled(bool b)
{
setPSProperty(batteryInstalledKey,
b ? kOSBooleanTrue : kOSBooleanFalse);
}
void
IOPMPowerSource::setIsCharging(bool b)
{
setPSProperty(chargingKey,
b ? kOSBooleanTrue : kOSBooleanFalse);
}
void
IOPMPowerSource::setAtWarnLevel(bool b)
{
setPSProperty(warnLevelKey,
b ? kOSBooleanTrue : kOSBooleanFalse);
}
void
IOPMPowerSource::setAtCriticalLevel(bool b)
{
setPSProperty(criticalLevelKey,
b ? kOSBooleanTrue : kOSBooleanFalse);
}
void
IOPMPowerSource::setCurrentCapacity(unsigned int val)
{
OSNumber *n = OSNumber::withNumber(val, 32);
setPSProperty(currentCapacityKey, n);
n->release();
}
void
IOPMPowerSource::setMaxCapacity(unsigned int val)
{
OSNumber *n = OSNumber::withNumber(val, 32);
setPSProperty(maxCapacityKey, n);
n->release();
}
void
IOPMPowerSource::setTimeRemaining(int val)
{
OSNumber *n = OSNumber::withNumber(val, 32);
setPSProperty(timeRemainingKey, n);
n->release();
}
void
IOPMPowerSource::setAmperage(int val)
{
OSNumber *n = OSNumber::withNumber(val, 32);
setPSProperty(amperageKey, n);
n->release();
}
void
IOPMPowerSource::setVoltage(unsigned int val)
{
OSNumber *n = OSNumber::withNumber(val, 32);
setPSProperty(voltageKey, n);
n->release();
}
void
IOPMPowerSource::setCycleCount(unsigned int val)
{
OSNumber *n = OSNumber::withNumber(val, 32);
setPSProperty(cycleCountKey, n);
n->release();
}
void
IOPMPowerSource::setAdapterInfo(int val)
{
OSNumber *n = OSNumber::withNumber(val, 32);
setPSProperty(adapterInfoKey, n);
n->release();
}
void
IOPMPowerSource::setLocation(int val)
{
OSNumber *n = OSNumber::withNumber(val, 32);
setPSProperty(locationKey, n);
n->release();
}
void
IOPMPowerSource::setErrorCondition(OSSymbol *s)
{
setPSProperty(errorConditionKey, s);
}
void
IOPMPowerSource::setManufacturer(OSSymbol *s)
{
setPSProperty(manufacturerKey, s);
}
void
IOPMPowerSource::setModel(OSSymbol *s)
{
setPSProperty(modelKey, s);
}
void
IOPMPowerSource::setSerial(OSSymbol *s)
{
setPSProperty(serialKey, s);
}
void
IOPMPowerSource::setLegacyIOBatteryInfo(OSDictionary *d)
{
setPSProperty(batteryInfoKey, d);
}
/*******************************************************************************
*
* PUBLIC Accessors. All the getters! Boo!
*
******************************************************************************/
OSObject *
IOPMPowerSource::getPSProperty(const OSSymbol *symmie)
{
if (!symmie) {
return NULL;
}
return properties->getObject(symmie);
}
bool
IOPMPowerSource::externalConnected(void)
{
return kOSBooleanTrue == properties->getObject(externalConnectedKey);
}
bool
IOPMPowerSource::externalChargeCapable(void)
{
return kOSBooleanTrue == properties->getObject(externalChargeCapableKey);
}
bool
IOPMPowerSource::batteryInstalled(void)
{
return kOSBooleanTrue == properties->getObject(batteryInstalledKey);
}
bool
IOPMPowerSource::isCharging(void)
{
return kOSBooleanTrue == properties->getObject(chargingKey);
}
bool
IOPMPowerSource::atWarnLevel(void)
{
return kOSBooleanTrue == properties->getObject(warnLevelKey);
}
bool
IOPMPowerSource::atCriticalLevel(void)
{
return kOSBooleanTrue == properties->getObject(criticalLevelKey);
}
unsigned int
IOPMPowerSource::currentCapacity(void)
{
OSNumber *n;
n = OSDynamicCast(OSNumber, properties->getObject(currentCapacityKey));
if (!n) {
return 0;
} else {
return (unsigned int)n->unsigned32BitValue();
}
}
unsigned int
IOPMPowerSource::maxCapacity(void)
{
OSNumber *n;
n = OSDynamicCast(OSNumber, properties->getObject(maxCapacityKey));
if (!n) {
return 0;
} else {
return (unsigned int)n->unsigned32BitValue();
}
}
unsigned int
IOPMPowerSource::capacityPercentRemaining(void)
{
unsigned int _currentCapacity = currentCapacity();
unsigned int _maxCapacity = maxCapacity();
if (0 == _maxCapacity) {
return 0;
} else {
return (100 * _currentCapacity) / _maxCapacity;
}
}
int
IOPMPowerSource::timeRemaining(void)
{
OSNumber *n;
n = OSDynamicCast(OSNumber, properties->getObject(timeRemainingKey));
if (!n) {
return 0;
} else {
return (int)n->unsigned32BitValue();
}
}
int
IOPMPowerSource::amperage(void)
{
OSNumber *n;
n = OSDynamicCast(OSNumber, properties->getObject(amperageKey));
if (!n) {
return 0;
} else {
return (int)n->unsigned32BitValue();
}
}
unsigned int
IOPMPowerSource::voltage(void)
{
OSNumber *n;
n = OSDynamicCast(OSNumber, properties->getObject(voltageKey));
if (!n) {
return 0;
} else {
return (unsigned int)n->unsigned32BitValue();
}
}
unsigned int
IOPMPowerSource::cycleCount(void)
{
OSNumber *n;
n = OSDynamicCast(OSNumber, properties->getObject(cycleCountKey));
if (!n) {
return 0;
} else {
return (unsigned int)n->unsigned32BitValue();
}
}
int
IOPMPowerSource::adapterInfo(void)
{
OSNumber *n;
n = OSDynamicCast(OSNumber, properties->getObject(adapterInfoKey));
if (!n) {
return 0;
} else {
return (int)n->unsigned32BitValue();
}
}
int
IOPMPowerSource::location(void)
{
OSNumber *n;
n = OSDynamicCast(OSNumber, properties->getObject(locationKey));
if (!n) {
return 0;
} else {
return (unsigned int)n->unsigned32BitValue();
}
}
OSSymbol *
IOPMPowerSource::errorCondition(void)
{
return OSDynamicCast(OSSymbol, properties->getObject(errorConditionKey));
}
OSSymbol *
IOPMPowerSource::manufacturer(void)
{
return OSDynamicCast(OSSymbol, properties->getObject(manufacturerKey));
}
OSSymbol *
IOPMPowerSource::model(void)
{
return OSDynamicCast(OSSymbol, properties->getObject(modelKey));
}
OSSymbol *
IOPMPowerSource::serial(void)
{
return OSDynamicCast(OSSymbol, properties->getObject(serialKey));
}
OSDictionary *
IOPMPowerSource::legacyIOBatteryInfo(void)
{
return OSDynamicCast(OSDictionary, properties->getObject(batteryInfoKey));
}