Loading...
iokit/Kernel/IOPMPowerSource.cpp xnu-792 xnu-8792.41.9
--- xnu/xnu-792/iokit/Kernel/IOPMPowerSource.cpp
+++ xnu/xnu-8792.41.9/iokit/Kernel/IOPMPowerSource.cpp
@@ -1,166 +1,584 @@
 /*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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 OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
+ * 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>
-
-#define super OSObject
-
-OSDefineMetaClassAndStructors(IOPMPowerSource, OSObject)
-
-// **********************************************************************************
+#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 (unsigned short whichBatteryIndex)
-{
-  if (!super::init ())
-    return false;
-
-  bBatteryIndex = whichBatteryIndex;
-  nextInList    = 0;
-
-  return true;
-}
-
-// **********************************************************************************
-// capacityPercentRemaining
+// *****************************************************************************
+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
 //
-// **********************************************************************************
-unsigned long IOPMPowerSource::capacityPercentRemaining (void)
-{
-   unsigned long percentage = 0;
-
-   if (bMaxCapacity > 0)
-     percentage = (bCurCapacity * 100) / bMaxCapacity;
- 
-   // always return a non-zero value unless the real capacity IS zero.
-   if (percentage == 0 && bCurCapacity > 0)
-     percentage = 1;
-
-   return percentage;
-}
-
-// **********************************************************************************
-// atWarnLevel
-//
-// **********************************************************************************
-bool IOPMPowerSource::atWarnLevel (void)
-{
-  return bFlags & kBatteryAtWarn;
-}
-
-// **********************************************************************************
-// acConnected
-//
-// **********************************************************************************
-bool IOPMPowerSource::acConnected (void)
-{
-  return bFlags & kACInstalled;
-}
-
-// **********************************************************************************
-// depleted
-//
-// **********************************************************************************
-bool IOPMPowerSource::depleted (void)
-{
-  return bFlags & kBatteryDepleted;
-}
-
-// **********************************************************************************
-// isInstalled
-//
-// **********************************************************************************
-bool IOPMPowerSource::isInstalled (void)
-{
-  return bFlags & kBatteryInstalled;
-}
-
-// **********************************************************************************
-// isCharging
-//
-// **********************************************************************************
-bool IOPMPowerSource::isCharging (void)
-{
-  return bFlags & kBatteryCharging;
-}
-
-// **********************************************************************************
-// timeRemaining
-//
-// **********************************************************************************
-unsigned long IOPMPowerSource::timeRemaining (void)
-{
-  return bTimeRemaining;
-}
-
-// **********************************************************************************
-// maxCapacity
-//
-// **********************************************************************************
-unsigned long IOPMPowerSource::maxCapacity (void)
-{
-  return bMaxCapacity;
-}
-
-// **********************************************************************************
-// curCapacity
-//
-// **********************************************************************************
-unsigned long IOPMPowerSource::curCapacity (void)
-{
-  return bCurCapacity;
-}
-
-// **********************************************************************************
-// currentDrawn
-//
-// **********************************************************************************
-long IOPMPowerSource::currentDrawn (void)
-{
-  return bCurrent;
-}
-
-// **********************************************************************************
-// voltage
-//
-// **********************************************************************************
-
-unsigned long IOPMPowerSource::voltage (void)
-{
-  return bVoltage;
-}
-
-// **********************************************************************************
+// *****************************************************************************
+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
 //
-// **********************************************************************************
-
-void IOPMPowerSource::updateStatus (void)
-{
-
-}
-
-
-
-
-
+// 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));
+}