/* * Copyright (c) 2001 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 * 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@ */ /* * Copyright (c) 2001 Apple Computer, Inc. All rights reserved. * * HISTORY * * 18-Dec-01 ebold created * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "batteryconfigd.h" #define kIOPMAppName "Power Management configd plugin" #define kIOPMPrefsPath "com.apple.PowerManagement.xml" #ifndef kIOPSUPSManagementClaimed #define kIOPSUPSManagementClaimed "State:/IOKit/UPSPowerManagementClaimed" #endif /* Power Management profile bits */ enum { kPMForceLowSpeedProfile = (1<<0), kPMREMSleepProfile = (1<<1) }; /* Global - systemEnergySettings * Keeps track of current Energy Saver settings. */ static CFMutableDictionaryRef systemEnergySettings = NULL; /* Global - currentPowerSource * Keeps track of current power - battery or AC */ static CFStringRef currentPowerSource = NULL; /* g_profiles * Tracks active PM usage profiles */ static unsigned long g_profiles = 0; // Global keys static CFStringRef EnergyPrefsKey; static SCDynamicStoreRef energyDS; static io_connect_t gPowerManager; /* activate_profiles * * A wrapper for IOPMActivatePMPreference. We get a chance here to apply "profiles" * to the Energy Saver settings before sending them to the kernel. * Profiles (like LidClosed or ForceLowSpeed) have affects like accelerating idle * times or forcing ReduceProcessorSpeed on. */ static IOReturn activate_profiles(CFMutableDictionaryRef d, CFStringRef s) { CFMutableDictionaryRef energy_settings; CFMutableDictionaryRef profiles_activated; CFMutableDictionaryRef tmp; IOReturn ret; CFNumberRef n1; int one = 1; //syslog(LOG_INFO, "g_profiles = %ld", g_profiles); if(g_profiles) { energy_settings = (CFMutableDictionaryRef)isA_CFDictionary(CFDictionaryGetValue(d, s)); if(!energy_settings) return kIOReturnError; profiles_activated = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, CFDictionaryGetCount(energy_settings), energy_settings); if(!profiles_activated) return kIOReturnError; n1 = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &one); // If the "force low speed" profile is set, flip the ReduceSpeed bit on if(g_profiles & kPMForceLowSpeedProfile) { if(n1) CFDictionarySetValue(profiles_activated, CFSTR(kIOPMReduceSpeedKey), n1); //syslog(LOG_INFO, "ForceLowSpeed activated"); } if(g_profiles & kPMREMSleepProfile) { if(n1) CFDictionarySetValue(profiles_activated, CFSTR(kIOPMDiskSleepKey), n1); if(n1) CFDictionarySetValue(profiles_activated, CFSTR(kIOPMSystemSleepKey), n1); if(n1) CFDictionarySetValue(profiles_activated, CFSTR(kIOPMDisplaySleepKey), n1); //syslog(LOG_INFO, "REMSleepProfile activated"); } CFRelease(n1); // Package the new, modified settings, in a way that // IOPMActivatePMPreferences will read them tmp = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(tmp, s, profiles_activated); ret = IOPMActivatePMPreference(tmp, s); CFRelease(profiles_activated); CFRelease(tmp); } else { ret = IOPMActivatePMPreference(d, s); } return ret; } /* ESPrefsHaveChanged * * Is the handler that configd calls when someone "applies" new Energy Saver * Preferences. Since the preferences have probably changed, we re-read them * from disk and transmit the new settings to the kernel. */ static void ESPrefsHaveChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) { CFRange array_range = CFRangeMake(0, CFArrayGetCount(changedKeys)); // If Power Management Preferences file has changed if(CFArrayContainsValue(changedKeys, array_range, EnergyPrefsKey)) { // re-read preferences into memory CFRelease(systemEnergySettings); systemEnergySettings = (CFMutableDictionaryRef)isA_CFDictionary(IOPMCopyPMPreferences()); // push new preferences out to the kernel //syslog(LOG_INFO, "PMConfigd: activating new preferences"); if(systemEnergySettings) activate_profiles(systemEnergySettings, currentPowerSource); } return; } /* isUPSPresent * * Argument: * CFTypeRef power_sources: The return value from IOPSCoyPowerSourcesInfo() * Return value: * CFTypeRef: handle for the system-power-managing UPS * NULL if no UPS is present */ static CFTypeRef isUPSPresent(CFTypeRef power_sources) { CFArrayRef array = isA_CFArray(IOPSCopyPowerSourcesList(power_sources)); CFTypeRef name = NULL; CFTypeRef name_ret = NULL; CFDictionaryRef ps; CFStringRef transport_type; int i, count; if(!array) return; count = CFArrayGetCount(array); name = NULL; // Iterate through power_sources for(i=0; i 0) { // Setup battery polling timer initializeBatteryPollingTimer(); } // Find out what the current power source is CFNumberGetValue(CFDictionaryGetValue( CFArrayGetValueAtIndex((CFArrayRef)battery_info,0), CFSTR("Flags")), kCFNumberSInt32Type,&flags); if(flags & kIOBatteryChargerConnect) { currentPowerSource = CFSTR(kIOPMACPowerKey); // AC } else { currentPowerSource = CFSTR(kIOPMBatteryPowerKey); // battery } CFRelease(battery_info); } else { // If no batteries are found, set currentPowerSource as AC currentPowerSource = CFSTR(kIOPMACPowerKey); } } //#define MAIN #ifdef MAIN int main(int argc, char **argv) { load(CFBundleGetMainBundle(), (argc > 1) ? TRUE : FALSE); prime(); CFRunLoopRun(); /* not reached */ exit(0); return 0; } #endif