#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOReturn.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <syslog.h>
#include "PrivateLib.h"
enum
{
PowerMangerScheduledShutdown = 1,
PowerMangerScheduledSleep
};
#define kPowerManagerActionNotificationName "com.apple.powermanager.action"
#define kPowerManagerActionKey "action"
#define kPowerManagerValueKey "value"
#define DUMMY_UPS_HEADER(myBundle) CFCopyLocalizedStringWithDefaultValue( \
CFSTR("WARNING!"), \
CFSTR("Localizable"), \
myBundle, \
CFSTR("Warning!"), \
NULL);
#define DUMMY_UPS_BODY(myBundle) CFCopyLocalizedStringWithDefaultValue( \
CFSTR("YOUR COMPUTER IS NOW RUNNING ON UPS BACKUP BATTERY. SAVE YOUR DOCUMENTS AND SHUTDOWN SOON."), \
CFSTR("Localizable"), \
myBundle, \
CFSTR("Your computer is now running on UPS backup battery. Save your documents and shutdown soon."), \
NULL);
#define DUMMY_BATT_HEADER(myBundle) CFCopyLocalizedStringWithDefaultValue( \
CFSTR("YOU ARE NOW RUNNING ON RESERVE BATTERY POWER."), \
CFSTR("Localizable"), \
myBundle, \
CFSTR("You are now running on reserve battery power."), \
NULL);
#define DUMMY_BATT_BODY(myBundle) CFCopyLocalizedStringWithDefaultValue( \
CFSTR("PLEASE CONNECT YOUR COMPUTER TO AC POWER. IF YOU DO NOT, YOUR COMPUTER WILL GO TO SLEEP IN A FEW MINUTES TO PRESERVE THE CONTENTS OF MEMORY."), \
CFSTR("Localizable"), \
myBundle, \
CFSTR("Please connect your computer to AC power. If you do not, your computer will go to sleep in a few minutes to preserve the contents of memory."), \
NULL);
__private_extern__ IOReturn
_setRootDomainProperty(
CFStringRef key,
CFTypeRef val)
{
mach_port_t masterPort;
io_iterator_t it;
io_registry_entry_t root_domain;
IOReturn ret;
IOMasterPort(bootstrap_port, &masterPort);
if(!masterPort) return kIOReturnError;
IOServiceGetMatchingServices(masterPort, IOServiceNameMatching("IOPMrootDomain"), &it);
if(!it) return kIOReturnError;
root_domain = (io_registry_entry_t)IOIteratorNext(it);
if(!root_domain) return kIOReturnError;
ret = IORegistryEntrySetCFProperty(root_domain, key, val);
IOObjectRelease(root_domain);
IOObjectRelease(it);
IOObjectRelease(masterPort);
return ret;
}
static void sendNotification(int command)
{
CFMutableDictionaryRef dict = NULL;
int numberOfSeconds = 600;
CFNumberRef secondsValue = CFNumberCreate( NULL, kCFNumberIntType, &numberOfSeconds );
CFNumberRef commandValue = CFNumberCreate( NULL, kCFNumberIntType, &command );
dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(dict, CFSTR(kPowerManagerActionKey), commandValue);
CFDictionarySetValue(dict, CFSTR(kPowerManagerValueKey), secondsValue);
CFNotificationCenterPostNotificationWithOptions ( CFNotificationCenterGetDistributedCenter(),
CFSTR(kPowerManagerActionNotificationName),
NULL, dict,
(kCFNotificationPostToAllSessions | kCFNotificationDeliverImmediately));
CFRelease(dict);
CFRelease(secondsValue);
CFRelease(commandValue);
}
__private_extern__ void _askNicelyThenShutdownSystem(void)
{
sendNotification(PowerMangerScheduledShutdown);
}
__private_extern__ void _askNicelyThenSleepSystem(void)
{
sendNotification(PowerMangerScheduledSleep);
}
__private_extern__ CFArrayRef _copyBatteryInfo(void)
{
static mach_port_t master_device_port = 0;
kern_return_t kr;
int ret;
CFArrayRef battery_info = NULL;
if(!master_device_port) kr = IOMasterPort(bootstrap_port,&master_device_port);
ret = IOPMCopyBatteryInfo(master_device_port, &battery_info);
if(ret != kIOReturnSuccess || !battery_info)
{
return NULL;
}
return battery_info;
}
__private_extern__ CFUserNotificationRef _showUPSWarning(void)
{
#ifndef STANDALONE
CFMutableDictionaryRef alert_dict;
SInt32 error;
CFUserNotificationRef note_ref;
CFBundleRef myBundle;
CFStringRef header_unlocalized;
CFStringRef message_unlocalized;
CFURLRef bundle_url;
myBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.SystemConfiguration.PowerManagement"));
alert_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if(!alert_dict) return NULL;
bundle_url = CFBundleCopyBundleURL(myBundle);
CFDictionarySetValue(alert_dict, kCFUserNotificationLocalizationURLKey, bundle_url);
CFRelease(bundle_url);
header_unlocalized = CFSTR("WARNING!");
message_unlocalized = CFSTR("YOUR COMPUTER IS NOW RUNNING ON UPS BACKUP BATTERY. SAVE YOUR DOCUMENTS AND SHUTDOWN SOON.");
CFDictionaryAddValue(alert_dict, kCFUserNotificationAlertHeaderKey, header_unlocalized);
CFDictionaryAddValue(alert_dict, kCFUserNotificationAlertMessageKey, message_unlocalized);
note_ref = CFUserNotificationCreate(kCFAllocatorDefault, 0, 0, &error, alert_dict);
CFRelease(alert_dict);
if(0 != error)
{
syslog(LOG_INFO, "pmcfgd: UPS warning error = %d\n", error);
return NULL;
}
return note_ref;
#endif // STANDALONE
}