146 lines
7.5 KiB
Objective-C
146 lines
7.5 KiB
Objective-C
//
|
|
// MGMPowerWatcher.m
|
|
// SoundNote
|
|
//
|
|
// Created by Mr. Gecko on 2/16/11.
|
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
|
|
//
|
|
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
// with or without fee is hereby granted, provided that the above copyright notice
|
|
// and this permission notice appear in all copies.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
|
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
|
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
//
|
|
|
|
#import "MGMPowerWatcher.h"
|
|
#import "MGMController.h"
|
|
#import <IOKit/IOKitLib.h>
|
|
#import <IOKit/ps/IOPSKeys.h>
|
|
#import <IOKit/ps/IOPowerSources.h>
|
|
|
|
static int lastPowerSource;
|
|
static BOOL lastChargingState;
|
|
static int lastBatteryTime;
|
|
|
|
static void powerNotification(void *context) {
|
|
CFTypeRef powerInfo = IOPSCopyPowerSourcesInfo();
|
|
NSArray *powerSources = (NSArray *)IOPSCopyPowerSourcesList(powerInfo);
|
|
|
|
for (int i=0; i<[powerSources count]; ++i) {
|
|
NSString *powerSource;
|
|
NSDictionary *powerSourceInfo;
|
|
int powerSourceType = -1;
|
|
BOOL charging = NO;
|
|
int batteryTime = -1;
|
|
int percentage = 0;
|
|
|
|
powerSource = [powerSources objectAtIndex:i];
|
|
powerSourceInfo = (NSDictionary *)IOPSGetPowerSourceDescription(powerInfo, powerSource);
|
|
|
|
if (![[powerSourceInfo objectForKey:[NSString stringWithUTF8String:kIOPSIsPresentKey]] boolValue])
|
|
continue;
|
|
|
|
if ([[powerSourceInfo objectForKey:[NSString stringWithUTF8String:kIOPSTransportTypeKey]] isEqual:[NSString stringWithUTF8String:kIOPSInternalType]]) {
|
|
NSString *currentState = [powerSourceInfo objectForKey:[NSString stringWithUTF8String:kIOPSPowerSourceStateKey]];
|
|
|
|
if ([currentState isEqual:[NSString stringWithUTF8String:kIOPSACPowerValue]])
|
|
powerSourceType = 0;
|
|
else if ([currentState isEqual:[NSString stringWithUTF8String:kIOPSBatteryPowerValue]])
|
|
powerSourceType = 1;
|
|
else
|
|
powerSourceType = -1;
|
|
|
|
charging = [[powerSourceInfo objectForKey:[NSString stringWithUTF8String:kIOPSIsChargingKey]] boolValue];
|
|
if (charging) {
|
|
batteryTime = [[powerSourceInfo objectForKey:[NSString stringWithUTF8String:kIOPSTimeToFullChargeKey]] intValue];
|
|
} else {
|
|
batteryTime = [[powerSourceInfo objectForKey:[NSString stringWithUTF8String:kIOPSTimeToEmptyKey]] intValue];
|
|
}
|
|
|
|
float currentCapacity = [[powerSourceInfo objectForKey:[NSString stringWithUTF8String:kIOPSCurrentCapacityKey]] floatValue];;
|
|
float maxCapacity = [[powerSourceInfo objectForKey:[NSString stringWithUTF8String:kIOPSMaxCapacityKey]] floatValue];;
|
|
percentage = roundf((currentCapacity/maxCapacity)*100.0);
|
|
} else {
|
|
powerSourceType = 2;
|
|
}
|
|
if (lastPowerSource!=powerSourceType) {
|
|
[(MGMPowerWatcher *)context powerSourceChanged:powerSourceType];
|
|
lastPowerSource = powerSourceType;
|
|
}
|
|
if (powerSourceType==0 && lastChargingState!=charging) {
|
|
[(MGMPowerWatcher *)context powerChargingStateChanged:charging percentage:percentage];
|
|
lastChargingState = charging;
|
|
}
|
|
if (batteryTime!=-1 && lastBatteryTime!=batteryTime) {
|
|
[(MGMPowerWatcher *)context powerTimeChanged:batteryTime];
|
|
lastBatteryTime = batteryTime;
|
|
}
|
|
}
|
|
|
|
[powerSources release];
|
|
CFRelease(powerInfo);
|
|
}
|
|
|
|
@implementation MGMPowerWatcher
|
|
- (id)init {
|
|
if ((self = [super init])) {
|
|
runLoop = IOPSNotificationCreateRunLoopSource(powerNotification, self);
|
|
if (runLoop!=NULL)
|
|
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoop, kCFRunLoopDefaultMode);
|
|
lastPowerSource = -1;
|
|
lastBatteryTime = -1;
|
|
batterWarned20 = NO;
|
|
batterWarned10 = NO;
|
|
batterWarned5 = NO;
|
|
}
|
|
return self;
|
|
}
|
|
- (void)dealloc {
|
|
[super dealloc];
|
|
}
|
|
|
|
- (void)powerSourceChanged:(int)theType {
|
|
NSString *name = (theType==0 ? @"Power Adapter" : (theType==1 ? @"Battery" : @"UPS"));
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"powersourcechanged", MGMNName, @"New Power Source", MGMNTitle, name, MGMNDescription, [NSImage imageNamed:(theType==0 ? @"BatteryCharging" : @"Battery")], MGMNIcon, nil]];
|
|
if (theType==0) {
|
|
batterWarned20 = NO;
|
|
batterWarned10 = NO;
|
|
batterWarned5 = NO;
|
|
lastBatteryTime = -1;
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"poweronac", MGMNName, @"Power Source", MGMNTitle, name, MGMNDescription, [NSImage imageNamed:@"BatteryCharging"], MGMNIcon, nil]];
|
|
} else if (theType==1) {
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"poweronbattery", MGMNName, @"Power Source", MGMNTitle, name, MGMNDescription, [NSImage imageNamed:@"Battery"], MGMNIcon, nil]];
|
|
} else if (theType==2) {
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"poweronups", MGMNName, @"Power Source", MGMNTitle, name, MGMNDescription, [NSImage imageNamed:@"Battery"], MGMNIcon, nil]];
|
|
}
|
|
}
|
|
- (void)powerChargingStateChanged:(BOOL)isCharging percentage:(int)thePercent {
|
|
if (isCharging) {
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"charging", MGMNName, @"Charging", MGMNTitle, [NSString stringWithFormat:@"%d%%", thePercent], MGMNDescription, [NSImage imageNamed:(isCharging ? @"BatteryCharging" : @"Battery")], MGMNIcon, nil]];
|
|
} else {
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"charged", MGMNName, @"Charged", MGMNTitle, [NSString stringWithFormat:@"%d%%", thePercent], MGMNDescription, [NSImage imageNamed:(isCharging ? @"BatteryCharging" : @"Battery")], MGMNIcon, nil]];
|
|
}
|
|
}
|
|
- (void)powerTimeChanged:(int)theTime {
|
|
if (lastBatteryTime==-1) {
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"batterytime", MGMNName, @"Battery Charging", MGMNTitle, [NSString stringWithFormat:@"There is %d minutes remaining.", theTime], MGMNDescription, [NSImage imageNamed:(lastChargingState ? @"BatteryCharging" : @"Battery")], MGMNIcon, nil]];
|
|
}
|
|
if (lastPowerSource!=0) {
|
|
if (theTime<=20 && theTime>10 && !batterWarned20) {
|
|
batterWarned20 = YES;
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"battery20minutes", MGMNName, @"Battery Warning", MGMNTitle, @"There is 20 minutes remaining.", MGMNDescription, [NSImage imageNamed:(lastChargingState ? @"BatteryCharging" : @"Battery")], MGMNIcon, nil]];
|
|
} else if (theTime<=10 && theTime>5 && !batterWarned10) {
|
|
batterWarned10 = YES;
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"battery10minutes", MGMNName, @"Battery Warning", MGMNTitle, @"There is 10 minutes remaining.", MGMNDescription, [NSImage imageNamed:(lastChargingState ? @"BatteryCharging" : @"Battery")], MGMNIcon, nil]];
|
|
} else if (theTime<=5 && !batterWarned5) {
|
|
batterWarned5 = YES;
|
|
[[MGMController sharedController] startNotificationWithInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"battery5minutes", MGMNName, @"Battery Warning", MGMNTitle, @"There is 5 minutes remaining.", MGMNDescription, [NSImage imageNamed:(lastChargingState ? @"BatteryCharging" : @"Battery")], MGMNIcon, nil]];
|
|
}
|
|
}
|
|
}
|
|
@end |