Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
829f0d779d | ||
|
|
292699e5f5 | ||
|
|
681f836fbb | ||
|
|
641e1a9640 | ||
|
|
8c7c44432f | ||
|
|
4101c011fe | ||
|
|
76b6271a0c | ||
|
|
4927324f85 | ||
|
|
eead935265 | ||
|
|
e5323156a8 | ||
|
|
2510865c24 |
@@ -1,14 +1,14 @@
|
||||
github "Alamofire/Alamofire" "4.7.2"
|
||||
github "Alamofire/AlamofireImage" "3.3.1"
|
||||
github "DigitaSecurity/CocoaMQTT" "0c56a9397d5d3fcea4472671e24014a5f31f9b15"
|
||||
github "DigitaSecurity/dnd" "35e24a1a4397c7b2c08b3bdc0df4a160ad340064"
|
||||
github "DigitaSecurity/CocoaAsyncSocket" "79a11b7036d0a77ca95de42cc1c92b5a4c50f0c9"
|
||||
github "DigitaSecurity/dnd" "02b4b2c6d495ebafda648e6ca6ebfbed7c20d0e7"
|
||||
github "SnapKit/SnapKit" "4.0.0"
|
||||
github "SwiftyJSON/SwiftyJSON" "4.1.0"
|
||||
github "emaloney/CleanroomLogger" "5.1.0"
|
||||
github "emqtt/CocoaMQTT" "4ef7bdcf3f0a754790dab8bff86dec67a695ee3c"
|
||||
github "getsentry/sentry-cocoa" "3.12.0"
|
||||
github "ninjaprox/NVActivityIndicatorView" "4.2.0"
|
||||
github "ninjaprox/NVActivityIndicatorView" "4.2.1"
|
||||
github "radex/SwiftyTimer" "2.0.0"
|
||||
github "realm/realm-cocoa" "v3.3.2"
|
||||
github "robbiehanson/CocoaAsyncSocket" "7.6.3"
|
||||
github "realm/realm-cocoa" "v3.7.1"
|
||||
github "saoudrizwan/Disk" "0.3.3"
|
||||
github "soffes/CommonCrypto" "v1.1.0"
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#import "Configure.h"
|
||||
#import "HelperComms.h"
|
||||
#import "AboutWindowController.h"
|
||||
#import "ErrorWindowController.h"
|
||||
#import "ConfigureWindowController.h"
|
||||
|
||||
//block for install/uninstall
|
||||
@@ -41,16 +40,10 @@ typedef void (^block)(NSNumber*);
|
||||
//configure window controller
|
||||
@property(nonatomic, retain)ConfigureWindowController* configureWindowController;
|
||||
|
||||
//error window controller
|
||||
@property(nonatomic, retain)ErrorWindowController* errorWindowController;
|
||||
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//display configuration window w/ 'install' || 'uninstall' button
|
||||
-(void)displayConfigureWindow:(BOOL)isInstalled;
|
||||
|
||||
//display error window
|
||||
-(void)displayErrorWindow:(NSDictionary*)errorInfo;
|
||||
|
||||
@end
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
@synthesize configureObj;
|
||||
|
||||
@synthesize aboutWindowController;
|
||||
@synthesize errorWindowController;
|
||||
@synthesize configureWindowController;
|
||||
|
||||
//main app interface
|
||||
@@ -41,17 +40,6 @@
|
||||
//start crash handler
|
||||
[SentryClient.sharedClient startCrashHandlerWithError:nil];
|
||||
|
||||
//make sure system is supported (lid)
|
||||
// if not, will inform user via alert
|
||||
if(YES != [self isSupported])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_ERR, @"device doesn't appear to have a lid (i.e. is unsupported)");
|
||||
|
||||
//exit
|
||||
[NSApp terminate:self];
|
||||
}
|
||||
|
||||
//alloc/init Config obj
|
||||
configureObj = [[Configure alloc] init];
|
||||
|
||||
@@ -61,51 +49,6 @@
|
||||
return;
|
||||
}
|
||||
|
||||
//check if there's a lid
|
||||
// if not, alert to tell user
|
||||
-(BOOL)isSupported
|
||||
{
|
||||
//flag
|
||||
BOOL supported = NO;
|
||||
|
||||
//alert
|
||||
NSAlert* alert = nil;
|
||||
|
||||
//no lid
|
||||
// can't support!
|
||||
if(stateUnavailable == getLidState())
|
||||
{
|
||||
//init alert
|
||||
alert = [[NSAlert alloc] init];
|
||||
|
||||
//set main text
|
||||
alert.messageText = @"Unsupported Device";
|
||||
|
||||
//set informative text
|
||||
alert.informativeText = [NSString stringWithFormat:@"'%@' does not appear to be a laptop", [[NSHost currentHost] localizedName]];
|
||||
|
||||
//add button
|
||||
[alert addButtonWithTitle:@"Ok"];
|
||||
|
||||
//set style
|
||||
alert.alertStyle = NSAlertStyleWarning;
|
||||
|
||||
//show it
|
||||
[alert runModal];
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//happy
|
||||
supported = YES;
|
||||
|
||||
bail:
|
||||
|
||||
return supported;
|
||||
|
||||
}
|
||||
|
||||
//exit when last window is closed
|
||||
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||
{
|
||||
@@ -143,58 +86,6 @@ bail:
|
||||
return;
|
||||
}
|
||||
|
||||
//display error window
|
||||
-(void)displayErrorWindow:(NSDictionary*)errorInfo
|
||||
{
|
||||
//alloc error window
|
||||
errorWindowController = [[ErrorWindowController alloc] initWithWindowNibName:@"ErrorWindowController"];
|
||||
|
||||
//main thread
|
||||
// just show UI alert, unless its fatal (then load URL)
|
||||
if(YES == [NSThread isMainThread])
|
||||
{
|
||||
//non-fatal errors
|
||||
// show error error popup
|
||||
if(YES != [errorInfo[KEY_ERROR_URL] isEqualToString:FATAL_ERROR_URL])
|
||||
{
|
||||
//display it
|
||||
// call this first to so that outlets are connected
|
||||
[self.errorWindowController display];
|
||||
|
||||
//configure it
|
||||
[self.errorWindowController configure:errorInfo];
|
||||
}
|
||||
//fatal error
|
||||
// launch browser to go to fatal error page, then exit
|
||||
else
|
||||
{
|
||||
//launch browser
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:errorInfo[KEY_ERROR_URL]]];
|
||||
|
||||
//then exit
|
||||
[NSApp terminate:self];
|
||||
}
|
||||
}
|
||||
//background thread
|
||||
// have to show error window on main thread
|
||||
else
|
||||
{
|
||||
//show alert
|
||||
// in main UI thread
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
|
||||
//display it
|
||||
// call this first to so that outlets are connected
|
||||
[self.errorWindowController display];
|
||||
|
||||
//configure it
|
||||
[self.errorWindowController configure:errorInfo];
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//menu handler for 'about'
|
||||
-(IBAction)displayAboutWindow:(id)sender
|
||||
|
||||
@@ -301,17 +301,12 @@ bail:
|
||||
//define block
|
||||
void (^block)(NSNumber *) = ^(NSNumber *result)
|
||||
{
|
||||
//callback from XPC will be a bg thread
|
||||
// so since we're updating UI, invoke on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
//signal sema
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
|
||||
//signal sema
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
|
||||
//save result
|
||||
wasInstalled = (BOOL)(result.intValue == 0);
|
||||
|
||||
});
|
||||
//save result
|
||||
wasInstalled = (BOOL)(result.intValue == 0);
|
||||
|
||||
};
|
||||
|
||||
//install
|
||||
@@ -377,17 +372,11 @@ bail:
|
||||
//define block
|
||||
void (^block)(NSNumber *) = ^(NSNumber *result)
|
||||
{
|
||||
//callback from XPC will be a bg thread
|
||||
// so since we're updating UI, invoke on main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
//signal sema
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
|
||||
//signal sema
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
|
||||
//save result
|
||||
wasUninstalled = (BOOL)(result.intValue == 0);
|
||||
|
||||
});
|
||||
//save result
|
||||
wasUninstalled = (BOOL)(result.intValue == 0);
|
||||
};
|
||||
|
||||
//init path to login item
|
||||
@@ -400,22 +389,24 @@ bail:
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to uninstall login item");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
//keep going though...
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"uninstalled login item (%@)", loginItem]);
|
||||
#ifdef DEBUG
|
||||
else
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"uninstalled login item (%@)", loginItem]);
|
||||
}
|
||||
#endif
|
||||
|
||||
//uninstall
|
||||
// also sets return var/flag
|
||||
// also sets return var/flag in block
|
||||
[xpcComms uninstall:full reply:block];
|
||||
|
||||
//wait for install to be completed by XPC
|
||||
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
||||
|
||||
bail:
|
||||
|
||||
return wasUninstalled;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -50,14 +50,22 @@
|
||||
// also brings window to front
|
||||
-(void)configure:(BOOL)isInstalled
|
||||
{
|
||||
//set title
|
||||
self.window.title = [NSString stringWithFormat:@"Do Not Disturb (v. %@)", getAppVersion()];
|
||||
|
||||
//init status msg
|
||||
[self.statusMsg setStringValue:@"evil maids: stay out! 🙅♀️🚪"];
|
||||
|
||||
//enable 'uninstall' button when app is installed already
|
||||
//app already installed?
|
||||
// enable 'uninstall' button
|
||||
// change install button to say 'upgrade'
|
||||
if(YES == isInstalled)
|
||||
{
|
||||
//enable
|
||||
//enable 'uninstall'
|
||||
self.uninstallButton.enabled = YES;
|
||||
|
||||
//set to 'upgrade'
|
||||
self.installButton.title = ACTION_UPGRADE;
|
||||
}
|
||||
//otherwise disable
|
||||
else
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -22,7 +22,7 @@
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="460" height="176"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
<view key="contentView" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="460" height="176"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
@@ -67,11 +67,6 @@
|
||||
<action selector="buttonHandler:" target="-2" id="1wC-Ls-D2F"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="K52-9g-sjn">
|
||||
<rect key="frame" x="138" y="109" width="243" height="67"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="dndText" id="WRg-I2-vkK"/>
|
||||
</imageView>
|
||||
<button hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QWu-qZ-Za2">
|
||||
<rect key="frame" x="414" y="33" width="25" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
@@ -83,6 +78,11 @@
|
||||
<action selector="info:" target="-2" id="tg3-SV-AH9"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hGI-P1-hcr">
|
||||
<rect key="frame" x="140" y="113" width="302" height="46"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="dndText" id="ZKa-1w-mi3"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
@@ -136,7 +136,7 @@
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="dndIcon" width="256" height="256"/>
|
||||
<image name="dndText" width="266.605712890625" height="34.354286193847656"/>
|
||||
<image name="dndText" width="164.57142639160156" height="21.188571929931641"/>
|
||||
<image name="objectiveSee" width="943" height="236"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
//
|
||||
// file: ErrorWindowController.h
|
||||
// project: DND (config)
|
||||
// description: error window (header)
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
@import Cocoa;
|
||||
|
||||
@interface ErrorWindowController : NSWindowController <NSWindowDelegate>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//main msg in window
|
||||
@property (weak, atomic) IBOutlet NSTextField *errMsg;
|
||||
|
||||
//sub msg in window
|
||||
@property (weak, atomic) IBOutlet NSTextField *errSubMsg;
|
||||
|
||||
//info/help/fix button
|
||||
@property (weak, atomic) IBOutlet NSButton *infoButton;
|
||||
|
||||
//close button
|
||||
@property (weak, atomic) IBOutlet NSButton *closeButton;
|
||||
|
||||
//(optional) url for 'Info' button
|
||||
@property(nonatomic, retain) NSURL* errorURL;
|
||||
|
||||
//flag indicating close button should exit app
|
||||
@property(atomic) BOOL shouldExit;
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//configure the object/window
|
||||
-(void)configure:(NSDictionary*)errorInfo;
|
||||
|
||||
//display (show) window
|
||||
-(void)display;
|
||||
|
||||
@end
|
||||
@@ -1,156 +0,0 @@
|
||||
//
|
||||
// file: ErrorWindowController.m
|
||||
// project: DND (config)
|
||||
// description: error window
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
#import "Consts.h"
|
||||
#import "ErrorWindowController.h"
|
||||
|
||||
@interface ErrorWindowController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation ErrorWindowController
|
||||
|
||||
@synthesize errorURL;
|
||||
@synthesize shouldExit;
|
||||
@synthesize closeButton;
|
||||
|
||||
//automatically called when nib is loaded
|
||||
// center window
|
||||
-(void)awakeFromNib
|
||||
{
|
||||
//center
|
||||
[self.window center];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//configure the object/window
|
||||
-(void)configure:(NSDictionary*)errorInfo
|
||||
{
|
||||
//set error msg
|
||||
self.errMsg.stringValue = errorInfo[KEY_ERROR_MSG];
|
||||
|
||||
//set error sub msg
|
||||
self.errSubMsg.stringValue = errorInfo[KEY_ERROR_SUB_MSG];
|
||||
|
||||
//save exit
|
||||
self.shouldExit = [errorInfo[KEY_ERROR_SHOULD_EXIT] boolValue];
|
||||
|
||||
//grab optional error url
|
||||
if(nil != errorInfo[KEY_ERROR_URL])
|
||||
{
|
||||
//extract/convert
|
||||
self.errorURL = [NSURL URLWithString:errorInfo[KEY_ERROR_URL]];
|
||||
}
|
||||
|
||||
//when exiting
|
||||
// change 'close' to 'exit'
|
||||
if(YES == self.shouldExit)
|
||||
{
|
||||
//change title
|
||||
self.closeButton.title = @"Exit";
|
||||
}
|
||||
|
||||
//for fatal errors
|
||||
// change 'Info' to 'help fix'
|
||||
if(YES == [[self.errorURL absoluteString] isEqualToString:FATAL_ERROR_URL])
|
||||
{
|
||||
//change title
|
||||
self.infoButton.title = @"Help Fix";
|
||||
}
|
||||
|
||||
//set delegate
|
||||
[self.window setDelegate:self];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//display (show) window
|
||||
-(void)display
|
||||
{
|
||||
//show (now configured), alert
|
||||
[self showWindow:self];
|
||||
|
||||
//make it key window
|
||||
[self.window makeKeyAndOrderFront:self];
|
||||
|
||||
//make window front
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
//make 'close' have focus
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
|
||||
|
||||
//make close button active
|
||||
[self.window makeFirstResponder:closeButton];
|
||||
|
||||
});
|
||||
|
||||
//make white
|
||||
[self.window setBackgroundColor: NSColor.whiteColor];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//invoked when user clicks '?' (help button)
|
||||
// open url with more info about the error(s)
|
||||
-(IBAction)help:(id)sender
|
||||
{
|
||||
#pragma unused(sender)
|
||||
|
||||
//if a url was specified
|
||||
// use that one
|
||||
if(nil != self.errorURL)
|
||||
{
|
||||
//open URL
|
||||
// invokes user's default browser
|
||||
[[NSWorkspace sharedWorkspace] openURL:self.errorURL];
|
||||
}
|
||||
//use default URL
|
||||
else
|
||||
{
|
||||
//open URL
|
||||
// invokes user's default browser
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:FATAL_ERROR_URL]];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//invoked when user clicks 'close'
|
||||
// just close window
|
||||
-(IBAction)close:(id)sender
|
||||
{
|
||||
#pragma unused(sender)
|
||||
|
||||
//close
|
||||
[self.window close];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//automatically invoked when window is closing
|
||||
// exit the app if specified...
|
||||
-(void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
#pragma unused(notification)
|
||||
|
||||
//check if should exit process
|
||||
// e.g. an error during install, etc
|
||||
if(YES == self.shouldExit)
|
||||
{
|
||||
//dbg msg
|
||||
//logMsg(LOG_DEBUG, @"exiting application");
|
||||
|
||||
//exit
|
||||
[NSApp terminate:self];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,85 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="ErrorWindowController">
|
||||
<connections>
|
||||
<outlet property="closeButton" destination="zbs-ul-WTJ" id="1fu-zv-brA"/>
|
||||
<outlet property="errMsg" destination="Act-U9-8G9" id="PMa-6M-gwu"/>
|
||||
<outlet property="errSubMsg" destination="tQ0-f2-G4C" id="4hz-9M-Gub"/>
|
||||
<outlet property="infoButton" destination="sNV-Jw-9dZ" id="qdf-xQ-ubf"/>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Do Not Disturb Error" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="744" y="427" width="380" height="137"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="380" height="137"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zbs-ul-WTJ">
|
||||
<rect key="frame" x="284" y="13" width="82" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Close" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Pjp-Se-SfK">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="close:" target="-2" id="sez-MW-4AE"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="tQ0-f2-G4C">
|
||||
<rect key="frame" x="114" y="49" width="248" height="36"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Label" id="sk0-EF-ZfG">
|
||||
<font key="font" size="11" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="Act-U9-8G9">
|
||||
<rect key="frame" x="114" y="88" width="248" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="ERROR msg" id="VCu-zh-Vcs">
|
||||
<font key="font" size="13" name="Menlo-Bold"/>
|
||||
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sNV-Jw-9dZ">
|
||||
<rect key="frame" x="202" y="13" width="82" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Info" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="L1w-RB-EC4">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="help:" target="-2" id="gCm-No-dHq"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sRj-I0-15e">
|
||||
<rect key="frame" x="12" y="35" width="92" height="92"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="dndIcon" id="9iG-ot-b7i"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="257" y="269.5"/>
|
||||
</window>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="dndIcon" width="256" height="256"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -13,11 +13,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.2.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.2.2</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright (c) 2018 Objective-See</string>
|
||||
<key>NSMainNibFile</key>
|
||||
|
||||
@@ -75,6 +75,14 @@ elif [ "${1}" == "-uninstall" ]; then
|
||||
if [[ "${2}" -eq "1" ]]; then
|
||||
rm -rf $INSTALL_DIRECTORY
|
||||
|
||||
#no other objective-see tools?
|
||||
# then delete that directory too
|
||||
baseDir=$(dirname $INSTALL_DIRECTORY)
|
||||
|
||||
if [ ! "$(ls -A $baseDir)" ]; then
|
||||
rm -rf $baseDir
|
||||
fi
|
||||
|
||||
#partial
|
||||
# just delete daemon, leaving prefs, etc
|
||||
else
|
||||
|
||||
@@ -9,7 +9,122 @@
|
||||
|
||||
@import Cocoa;
|
||||
|
||||
#import "Consts.h"
|
||||
#import "Logging.h"
|
||||
#import "utilities.h"
|
||||
#import "Configure.h"
|
||||
|
||||
//cmdline interface
|
||||
// install or uninstall
|
||||
BOOL cmdlineInterface(int action);
|
||||
|
||||
//main interface
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, (const char **) argv);
|
||||
//status
|
||||
int status = -1;
|
||||
|
||||
//cmdline install?
|
||||
if(YES == [[[NSProcessInfo processInfo] arguments] containsObject:CMDLINE_FLAG_INSTALL])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"performing commandline install");
|
||||
|
||||
//install
|
||||
if(YES != cmdlineInterface(ACTION_INSTALL_FLAG))
|
||||
{
|
||||
//err msg
|
||||
printf("\nDND ERROR: install failed\n\n");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
printf("DND: install ok!\n");
|
||||
|
||||
//happy
|
||||
status = 0;
|
||||
}
|
||||
|
||||
//cmdline uninstall?
|
||||
else if(YES == [[[NSProcessInfo processInfo] arguments] containsObject:CMDLINE_FLAG_UNINSTALL])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"performing commandline uninstall");
|
||||
|
||||
//install
|
||||
if(YES != cmdlineInterface(ACTION_UNINSTALL_FLAG))
|
||||
{
|
||||
//err msg
|
||||
printf("\nDND ERROR: uninstall failed\n\n");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
printf("DND: uninstall ok!\n");
|
||||
|
||||
//happy
|
||||
status = 0;
|
||||
}
|
||||
|
||||
//default run mode
|
||||
// just kick off main app logic
|
||||
else
|
||||
{
|
||||
//app main
|
||||
status = NSApplicationMain(argc, (const char **) argv);
|
||||
}
|
||||
|
||||
bail:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//cmdline interface
|
||||
// install or uninstall
|
||||
BOOL cmdlineInterface(int action)
|
||||
{
|
||||
//flag
|
||||
BOOL wasConfigured = NO;
|
||||
|
||||
//configure obj
|
||||
Configure* configure = nil;
|
||||
|
||||
//alloc/init
|
||||
configure = [[Configure alloc] init];
|
||||
|
||||
//first check root
|
||||
if(0 != geteuid())
|
||||
{
|
||||
//err msg
|
||||
printf("\nDND ERROR: cmdline interface actions require root!\n\n");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//configure
|
||||
wasConfigured = [configure configure:action];
|
||||
if(YES != wasConfigured)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//happy
|
||||
wasConfigured = YES;
|
||||
|
||||
bail:
|
||||
|
||||
//cleanup
|
||||
if(nil != configure)
|
||||
{
|
||||
//cleanup
|
||||
[configure removeHelper];
|
||||
}
|
||||
|
||||
return wasConfigured;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ dispatch_source_t dispatchSource = nil;
|
||||
|
||||
//configure
|
||||
// pass in 'install' flag
|
||||
result = [NSNumber numberWithInt:[self configure:app arguements:@[@"-install"]]];
|
||||
result = [NSNumber numberWithInt:[self configure:app arguements:@[CMDLINE_FLAG_INSTALL]]];
|
||||
|
||||
//reply to client
|
||||
reply(result);
|
||||
@@ -57,7 +57,7 @@ dispatch_source_t dispatchSource = nil;
|
||||
|
||||
//configure
|
||||
// pass in 'uninstall' flag, and partial/full
|
||||
result = [NSNumber numberWithInt:[self configure:app arguements:@[@"-uninstall", [NSNumber numberWithBool:full].stringValue]]];
|
||||
result = [NSNumber numberWithInt:[self configure:app arguements:@[CMDLINE_FLAG_UNINSTALL, [NSNumber numberWithBool:full].stringValue]]];
|
||||
|
||||
//reply to client
|
||||
reply(result);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<key>CFBundleName</key>
|
||||
<string>helper</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.2.2</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright (c) 2018 Objective-See</string>
|
||||
<key>SMAuthorizedClients</key>
|
||||
|
||||
@@ -11,22 +11,20 @@
|
||||
4BE4906110445E13006BE471 /* Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4905510445DDD006BE471 /* Helper.m */; };
|
||||
4BE4906410445F2F006BE471 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BE4906310445F2F006BE471 /* Security.framework */; };
|
||||
4BE4906810445F36006BE471 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BE4906710445F36006BE471 /* ServiceManagement.framework */; };
|
||||
4BE49092104463A0006BE471 /* com.objective-see.dnd.installer.helper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4BE4905D10445E0A006BE471 /* com.objective-see.dnd.installer.helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
4BE49092104463A0006BE471 /* com.objective-see.dnd.installer.helper in Copy Helper */ = {isa = PBXBuildFile; fileRef = 4BE4905D10445E0A006BE471 /* com.objective-see.dnd.installer.helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
||||
BF04235611C0531400431286 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = BF04235511C0531400431286 /* AppDelegate.m */; };
|
||||
BF65C19111B985C0007C20AB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF65C19011B985C0007C20AB /* MainMenu.xib */; };
|
||||
CD17D53B20104DD700F798D7 /* Logging.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D53820104DD700F798D7 /* Logging.m */; };
|
||||
CD17D54D20104EE700F798D7 /* ErrorWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD17D54320104EE600F798D7 /* ErrorWindowController.xib */; };
|
||||
CD17D54E20104EE700F798D7 /* AboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD17D54420104EE700F798D7 /* AboutWindow.xib */; };
|
||||
CD17D54F20104EE700F798D7 /* Configure.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D54720104EE700F798D7 /* Configure.m */; };
|
||||
CD17D55020104EE700F798D7 /* ConfigureWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D54820104EE700F798D7 /* ConfigureWindowController.m */; };
|
||||
CD17D55120104EE700F798D7 /* ConfigureWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD17D54920104EE700F798D7 /* ConfigureWindowController.xib */; };
|
||||
CD17D55220104EE700F798D7 /* ErrorWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D54A20104EE700F798D7 /* ErrorWindowController.m */; };
|
||||
CD17D55320104EE700F798D7 /* AboutWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D54B20104EE700F798D7 /* AboutWindowController.m */; };
|
||||
CD17D55E201148F900F798D7 /* configure.sh in Resources */ = {isa = PBXBuildFile; fileRef = CD17D55D201148F900F798D7 /* configure.sh */; };
|
||||
CD17D56320116C3800F798D7 /* com.objective-see.dnd.plist in Resources */ = {isa = PBXBuildFile; fileRef = CD17D56220116C3800F798D7 /* com.objective-see.dnd.plist */; };
|
||||
CD20A0D02057992F0044BCC5 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0CF2057992F0044BCC5 /* Sentry.framework */; };
|
||||
CD20A0D320579A380044BCC5 /* Sentry.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CD20A0CF2057992F0044BCC5 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
CD20A0D320579A380044BCC5 /* Sentry.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0CF2057992F0044BCC5 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
CD2F4082204B462E0066673E /* dndText.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC24A20226DFB0032F2E6 /* dndText.png */; };
|
||||
CD3307AE203567D500F10D71 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD3307AD203567D400F10D71 /* Assets.xcassets */; };
|
||||
CD73DA912004629D001FFC84 /* HelperInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CD73DA902004629D001FFC84 /* HelperInterface.m */; };
|
||||
@@ -53,24 +51,26 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
4BE49098104463C5006BE471 /* CopyFiles */ = {
|
||||
4BE49098104463C5006BE471 /* Copy Helper */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = Contents/Library/LaunchServices;
|
||||
dstSubfolderSpec = 1;
|
||||
files = (
|
||||
4BE49092104463A0006BE471 /* com.objective-see.dnd.installer.helper in CopyFiles */,
|
||||
4BE49092104463A0006BE471 /* com.objective-see.dnd.installer.helper in Copy Helper */,
|
||||
);
|
||||
name = "Copy Helper";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CD20A0D220579A1B0044BCC5 /* CopyFiles */ = {
|
||||
CD20A0D220579A1B0044BCC5 /* Copy Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
CD20A0D320579A380044BCC5 /* Sentry.framework in CopyFiles */,
|
||||
CD20A0D320579A380044BCC5 /* Sentry.framework in Copy Frameworks */,
|
||||
);
|
||||
name = "Copy Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
@@ -93,16 +93,13 @@
|
||||
CD17D53A20104DD700F798D7 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../shared/Logging.h; sourceTree = "<group>"; };
|
||||
CD17D53E20104E5A00F798D7 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../../shared/Consts.h; sourceTree = "<group>"; };
|
||||
CD17D54220104EE600F798D7 /* AboutWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutWindowController.h; sourceTree = "<group>"; };
|
||||
CD17D54320104EE600F798D7 /* ErrorWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ErrorWindowController.xib; sourceTree = "<group>"; };
|
||||
CD17D54420104EE700F798D7 /* AboutWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AboutWindow.xib; sourceTree = "<group>"; };
|
||||
CD17D54520104EE700F798D7 /* Configure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Configure.h; sourceTree = "<group>"; };
|
||||
CD17D54620104EE700F798D7 /* ConfigureWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigureWindowController.h; sourceTree = "<group>"; };
|
||||
CD17D54720104EE700F798D7 /* Configure.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Configure.m; sourceTree = "<group>"; };
|
||||
CD17D54820104EE700F798D7 /* ConfigureWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConfigureWindowController.m; sourceTree = "<group>"; };
|
||||
CD17D54920104EE700F798D7 /* ConfigureWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConfigureWindowController.xib; sourceTree = "<group>"; };
|
||||
CD17D54A20104EE700F798D7 /* ErrorWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ErrorWindowController.m; sourceTree = "<group>"; };
|
||||
CD17D54B20104EE700F798D7 /* AboutWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutWindowController.m; sourceTree = "<group>"; };
|
||||
CD17D54C20104EE700F798D7 /* ErrorWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ErrorWindowController.h; sourceTree = "<group>"; };
|
||||
CD17D55D201148F900F798D7 /* configure.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.sh; sourceTree = "<group>"; };
|
||||
CD17D56220116C3800F798D7 /* com.objective-see.dnd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "com.objective-see.dnd.plist"; path = "../launchDaemon/launchDaemon/com.objective-see.dnd.plist"; sourceTree = "<group>"; };
|
||||
CD18D64C200DA301005609F9 /* XPCProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCProtocol.h; path = Shared/XPCProtocol.h; sourceTree = SOURCE_ROOT; };
|
||||
@@ -190,9 +187,6 @@
|
||||
CD17D54620104EE700F798D7 /* ConfigureWindowController.h */,
|
||||
CD17D54820104EE700F798D7 /* ConfigureWindowController.m */,
|
||||
CD17D54920104EE700F798D7 /* ConfigureWindowController.xib */,
|
||||
CD17D54C20104EE700F798D7 /* ErrorWindowController.h */,
|
||||
CD17D54A20104EE700F798D7 /* ErrorWindowController.m */,
|
||||
CD17D54320104EE600F798D7 /* ErrorWindowController.xib */,
|
||||
CD73DA98200490B4001FFC84 /* HelperComms.h */,
|
||||
CD73DA97200490B4001FFC84 /* HelperComms.m */,
|
||||
4BE4904C10445D49006BE471 /* Info.plist */,
|
||||
@@ -286,9 +280,9 @@
|
||||
8D1107290486CEB800E47090 /* Resources */,
|
||||
8D11072C0486CEB800E47090 /* Sources */,
|
||||
8D11072E0486CEB800E47090 /* Frameworks */,
|
||||
4BE49098104463C5006BE471 /* CopyFiles */,
|
||||
4BE49098104463C5006BE471 /* Copy Helper */,
|
||||
CD17D55F20115E5E00F798D7 /* ShellScript */,
|
||||
CD20A0D220579A1B0044BCC5 /* CopyFiles */,
|
||||
CD20A0D220579A1B0044BCC5 /* Copy Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -307,7 +301,7 @@
|
||||
29B97313FDCFA39411CA2CEA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0920;
|
||||
LastUpgradeCheck = 0930;
|
||||
TargetAttributes = {
|
||||
4BE4905C10445E0A006BE471 = {
|
||||
DevelopmentTeam = VBG97UB4TA;
|
||||
@@ -342,7 +336,6 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CD2F4082204B462E0066673E /* dndText.png in Resources */,
|
||||
CD17D54D20104EE700F798D7 /* ErrorWindowController.xib in Resources */,
|
||||
CDAAC24C20226DFB0032F2E6 /* logo.png in Resources */,
|
||||
CD17D56320116C3800F798D7 /* com.objective-see.dnd.plist in Resources */,
|
||||
CDAAC24B20226DFB0032F2E6 /* objectiveSee.png in Resources */,
|
||||
@@ -369,7 +362,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "cp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\n\nrm -rf \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources/Do Not Disturb.bundle\"\ncp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb.bundle\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"";
|
||||
shellScript = "#archiving\nif [[ $BUILT_PRODUCTS_DIR = *\"ArchiveIntermediates\"* ]]; then\n\ncp -R -f \"$PROJECT_TEMP_ROOT/UninstalledProducts/macosx/Do Not Disturb.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\ncp -R -f \"$PROJECT_TEMP_ROOT/UninstalledProducts/macosx/Do Not Disturb.bundle\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\n\n#normal build\nelse\n\ncp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\nrm -rf \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources/Do Not Disturb.bundle\"\ncp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb.bundle\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\n\nfi\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
@@ -390,7 +383,6 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CD17D55220104EE700F798D7 /* ErrorWindowController.m in Sources */,
|
||||
4BE4905110445D49006BE471 /* main.m in Sources */,
|
||||
CD73DA942004633A001FFC84 /* HelperListener.m in Sources */,
|
||||
CD17D55320104EE700F798D7 /* AboutWindowController.m in Sources */,
|
||||
@@ -489,6 +481,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd.installer";
|
||||
PRODUCT_NAME = "Do Not Disturb Installer";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = NO;
|
||||
VALID_ARCHS = x86_64;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -511,6 +504,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd.installer";
|
||||
PRODUCT_NAME = "Do Not Disturb Installer";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = NO;
|
||||
VALID_ARCHS = x86_64;
|
||||
};
|
||||
name = Release;
|
||||
@@ -529,6 +523,7 @@
|
||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||
@@ -580,6 +575,7 @@
|
||||
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
@@ -68,7 +68,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@@ -88,7 +87,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -15,13 +15,15 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.2.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.2.2</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2018 Objective-See. All rights reserved.</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string></string>
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
</dict>
|
||||
|
||||
@@ -55,8 +55,11 @@
|
||||
CD256E062050DE9B00768457 /* ThunderboltMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = CD256DF32050DE4C00768457 /* ThunderboltMonitor.m */; };
|
||||
CD256E072050DE9B00768457 /* USBMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = CD256DF52050DE4C00768457 /* USBMonitor.m */; };
|
||||
CD256E082050DE9B00768457 /* UserAuthMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = CD256DED2050DE4B00768457 /* UserAuthMonitor.m */; };
|
||||
CD2C85F42119D9D5007CF784 /* LidTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = CD27BC6321139AD70017AEFD /* LidTrigger.m */; };
|
||||
CD2C85F82119FC02007CF784 /* DeviceTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = CD2C85F52119FB2A007CF784 /* DeviceTrigger.m */; };
|
||||
CD2C85FC211A0084007CF784 /* PowerTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = CD2C85FA211A006F007CF784 /* PowerTrigger.m */; };
|
||||
CDA993A62048905D00C1E9CD /* FrameworkInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA993A42048905D00C1E9CD /* FrameworkInterface.m */; };
|
||||
CE60F9C91FC9BBE500EFFDDA /* Lid.m in Sources */ = {isa = PBXBuildFile; fileRef = CE60F9C81FC9BBE500EFFDDA /* Lid.m */; };
|
||||
CE60F9C91FC9BBE500EFFDDA /* Triggers.m in Sources */ = {isa = PBXBuildFile; fileRef = CE60F9C81FC9BBE500EFFDDA /* Triggers.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -179,13 +182,19 @@
|
||||
CD256DF82050DE4C00768457 /* Monitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Monitor.h; path = launchDaemon/monitor/Monitor.h; sourceTree = SOURCE_ROOT; };
|
||||
CD256DFF2050DE6600768457 /* ProcListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProcListener.h; path = launchDaemon/monitor/ProcListener.h; sourceTree = SOURCE_ROOT; };
|
||||
CD256E002050DE6600768457 /* ProcListener.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProcListener.m; path = launchDaemon/monitor/ProcListener.m; sourceTree = SOURCE_ROOT; };
|
||||
CD27BC6321139AD70017AEFD /* LidTrigger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LidTrigger.m; path = triggers/LidTrigger.m; sourceTree = "<group>"; };
|
||||
CD27BC6421139AD70017AEFD /* LidTrigger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LidTrigger.h; path = triggers/LidTrigger.h; sourceTree = "<group>"; };
|
||||
CD2C85F52119FB2A007CF784 /* DeviceTrigger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DeviceTrigger.m; path = triggers/DeviceTrigger.m; sourceTree = "<group>"; };
|
||||
CD2C85F62119FB2A007CF784 /* DeviceTrigger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeviceTrigger.h; path = triggers/DeviceTrigger.h; sourceTree = "<group>"; };
|
||||
CD2C85F9211A006F007CF784 /* PowerTrigger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PowerTrigger.h; path = triggers/PowerTrigger.h; sourceTree = "<group>"; };
|
||||
CD2C85FA211A006F007CF784 /* PowerTrigger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PowerTrigger.m; path = triggers/PowerTrigger.m; sourceTree = "<group>"; };
|
||||
CD3307C5203639AD00F10D71 /* procInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = procInfo.h; path = launchDaemon/libs/procInfo.h; sourceTree = "<group>"; };
|
||||
CD3307C82036518400F10D71 /* main.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = main.h; sourceTree = "<group>"; };
|
||||
CDA993A32048905D00C1E9CD /* FrameworkInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FrameworkInterface.h; sourceTree = "<group>"; };
|
||||
CDA993A42048905D00C1E9CD /* FrameworkInterface.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FrameworkInterface.m; sourceTree = "<group>"; };
|
||||
CDAAC245202259B50032F2E6 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../../shared/Consts.h; sourceTree = "<group>"; };
|
||||
CE60F9C71FC9BBE500EFFDDA /* Lid.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Lid.h; sourceTree = "<group>"; };
|
||||
CE60F9C81FC9BBE500EFFDDA /* Lid.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Lid.m; sourceTree = "<group>"; };
|
||||
CE60F9C71FC9BBE500EFFDDA /* Triggers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Triggers.h; sourceTree = "<group>"; };
|
||||
CE60F9C81FC9BBE500EFFDDA /* Triggers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Triggers.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -277,12 +286,13 @@
|
||||
7D7755D21F02DF9500D0017D /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD27BC6221139A800017AEFD /* triggers */,
|
||||
CD256DEC2050DE3200768457 /* monitor */,
|
||||
7D7756071F05D62E00D0017D /* shared */,
|
||||
7DD2BF721F1E9CE700B33214 /* NSMutableArray+QueueAdditions.h */,
|
||||
7DD2BF731F1E9CE700B33214 /* NSMutableArray+QueueAdditions.m */,
|
||||
CE60F9C71FC9BBE500EFFDDA /* Lid.h */,
|
||||
CE60F9C81FC9BBE500EFFDDA /* Lid.m */,
|
||||
CE60F9C71FC9BBE500EFFDDA /* Triggers.h */,
|
||||
CE60F9C81FC9BBE500EFFDDA /* Triggers.m */,
|
||||
CDA993A32048905D00C1E9CD /* FrameworkInterface.h */,
|
||||
CDA993A42048905D00C1E9CD /* FrameworkInterface.m */,
|
||||
CD227869204648E000C72C76 /* Preferences.h */,
|
||||
@@ -336,6 +346,19 @@
|
||||
path = monitor;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CD27BC6221139A800017AEFD /* triggers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD2C85F9211A006F007CF784 /* PowerTrigger.h */,
|
||||
CD2C85FA211A006F007CF784 /* PowerTrigger.m */,
|
||||
CD2C85F62119FB2A007CF784 /* DeviceTrigger.h */,
|
||||
CD2C85F52119FB2A007CF784 /* DeviceTrigger.m */,
|
||||
CD27BC6421139AD70017AEFD /* LidTrigger.h */,
|
||||
CD27BC6321139AD70017AEFD /* LidTrigger.m */,
|
||||
);
|
||||
name = triggers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CD3307C42036399900F10D71 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -393,7 +416,7 @@
|
||||
7D7755C81F02DF9400D0017D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 0930;
|
||||
ORGANIZATIONNAME = "Objective-See";
|
||||
TargetAttributes = {
|
||||
2063725A203DC70A006D4C38 = {
|
||||
@@ -446,6 +469,9 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CD2C85FC211A0084007CF784 /* PowerTrigger.m in Sources */,
|
||||
CD2C85F82119FC02007CF784 /* DeviceTrigger.m in Sources */,
|
||||
CD2C85F42119D9D5007CF784 /* LidTrigger.m in Sources */,
|
||||
CD20869B208E8F0200BA1D0A /* VolumeMonitor.m in Sources */,
|
||||
CD256E022050DE9B00768457 /* ProcListener.m in Sources */,
|
||||
CD256E032050DE9B00768457 /* AuthEvent.m in Sources */,
|
||||
@@ -457,7 +483,7 @@
|
||||
CD22786C20464A6E00C72C76 /* Preferences.m in Sources */,
|
||||
CDA993A62048905D00C1E9CD /* FrameworkInterface.m in Sources */,
|
||||
7D46FEFF1F5E41F000FEB0F8 /* UserCommsListener.m in Sources */,
|
||||
CE60F9C91FC9BBE500EFFDDA /* Lid.m in Sources */,
|
||||
CE60F9C91FC9BBE500EFFDDA /* Triggers.m in Sources */,
|
||||
7DD2BF761F1E9CE700B33214 /* NSMutableArray+QueueAdditions.m in Sources */,
|
||||
7DD2BF681F1DC42700B33214 /* Utilities.m in Sources */,
|
||||
7DD2BF771F1E9CE700B33214 /* Queue.m in Sources */,
|
||||
@@ -537,6 +563,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@@ -544,6 +571,7 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@@ -590,6 +618,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@@ -597,6 +626,7 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@@ -642,6 +672,7 @@
|
||||
OTHER_CODE_SIGN_FLAGS = "";
|
||||
PRODUCT_NAME = "Do Not Disturb";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -665,6 +696,7 @@
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = "Do Not Disturb";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
//
|
||||
// file: Lid.h
|
||||
// project: DND (launch daemon)
|
||||
// description: monitor and alert logic for lid open events (header)
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Utilities.h"
|
||||
#import <dnd/dnd-Swift.h>
|
||||
|
||||
@import Foundation;
|
||||
|
||||
#import <IOKit/IOKitLib.h>
|
||||
#import <IOKit/pwr_mgt/IOPM.h>
|
||||
|
||||
/* FUNCTIONS */
|
||||
|
||||
//check if user auth'd
|
||||
// a) within last 10 seconds
|
||||
// b) via biometrics (touchID)
|
||||
BOOL authViaTouchID(void);
|
||||
|
||||
/* CLASS INTERFACE */
|
||||
|
||||
@interface Lid : NSObject <DNDClientMacDelegate>
|
||||
{
|
||||
//lid state
|
||||
LidState lidState;
|
||||
|
||||
//dispatch queue
|
||||
dispatch_queue_t dispatchQ;
|
||||
|
||||
//notification port
|
||||
IONotificationPortRef notificationPort;
|
||||
|
||||
//notification object
|
||||
io_object_t notification;
|
||||
}
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
//client
|
||||
@property(nonatomic, retain)DNDClientMac *client;
|
||||
|
||||
//dismiss dispatch group
|
||||
@property(nonatomic, retain)dispatch_group_t dispatchGroup;
|
||||
|
||||
//dispatch group flag
|
||||
@property BOOL dispatchGroupEmpty;
|
||||
|
||||
//dispatch blocks
|
||||
@property(nonatomic, retain)NSMutableArray* dispatchBlocks;
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//check if client should be init'd
|
||||
-(BOOL)shouldInitClient;
|
||||
|
||||
//init dnd client
|
||||
-(BOOL)clientInit;
|
||||
|
||||
//cancel all dipatch blocks
|
||||
-(void)cancelDispatchBlocks;
|
||||
|
||||
//register for notifications
|
||||
-(BOOL)register4Notifications;
|
||||
|
||||
//register for notifications
|
||||
-(void)unregister4Notifications;
|
||||
|
||||
//proces lid open event
|
||||
-(void)processEvent:(NSDate*)timestamp;
|
||||
|
||||
//execute action
|
||||
-(int)executeAction:(NSString*)path user:(NSString*)user;
|
||||
|
||||
@end
|
||||
@@ -7,16 +7,16 @@
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Lid.h"
|
||||
#import "consts.h"
|
||||
#import "logging.h"
|
||||
#import "Triggers.h"
|
||||
#import "Preferences.h"
|
||||
#import "FrameworkInterface.h"
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
//lid obj
|
||||
extern Lid* lid;
|
||||
//trigger obj
|
||||
extern Triggers* triggers;
|
||||
|
||||
//DND framework interface obj
|
||||
extern FrameworkInterface* framework;
|
||||
@@ -160,28 +160,27 @@ bail:
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"updating preferences (%@)", updates]);
|
||||
|
||||
//user setting state?
|
||||
// toggle the state of the daemon (lid) watcher too
|
||||
// toggle the state of the daemon triggers too
|
||||
if(nil != updates[PREF_IS_DISABLED])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"client toggling state: %@", updates[PREF_IS_DISABLED]]);
|
||||
|
||||
//disable?
|
||||
//disable triggers
|
||||
if(YES == [updates[PREF_IS_DISABLED] boolValue])
|
||||
{
|
||||
//dbg msg
|
||||
// and log to file
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, @"disabling...");
|
||||
|
||||
//unregister for lid notifications
|
||||
[lid unregister4Notifications];
|
||||
//turn off all triggers
|
||||
[triggers toggle:ALL_TRIGGERS state:NSOffState];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"unregistered for lid change notifications");
|
||||
logMsg(LOG_DEBUG, @"disabled triggers");
|
||||
|
||||
//cancel all lid notifications
|
||||
// ...will also disconnect client
|
||||
[lid cancelDispatchBlocks];
|
||||
//cancel all dispatch blocks
|
||||
[triggers cancelDispatchBlocks];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"cancelled all dispatch blocks (disconnecting any connected iOS client)");
|
||||
@@ -190,21 +189,88 @@ bail:
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:DISMISS_NOTIFICATION object:nil userInfo:nil];
|
||||
}
|
||||
|
||||
//enable?
|
||||
//enable triggers
|
||||
else
|
||||
{
|
||||
//dbg msg
|
||||
// and log to file
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, @"enabling...");
|
||||
|
||||
//register for lid notifications
|
||||
[lid register4Notifications];
|
||||
|
||||
//turn off all triggers
|
||||
[triggers toggle:ALL_TRIGGERS state:NSOnState];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"registered for lid change notifications");
|
||||
logMsg(LOG_DEBUG, @"enabled (all) triggers");
|
||||
}
|
||||
}
|
||||
|
||||
//toggle lid triggers
|
||||
if(nil != updates[PREF_LID_TRIGGER])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"toggling lid notifications");
|
||||
|
||||
//enable lid trigger
|
||||
if(YES == [updates[PREF_LID_TRIGGER] boolValue])
|
||||
{
|
||||
//enable
|
||||
[triggers toggle:LID_TRIGGER state:NSOnState];
|
||||
}
|
||||
|
||||
//disable lid trigger
|
||||
else
|
||||
{
|
||||
//disable
|
||||
[triggers toggle:LID_TRIGGER state:NSOffState];
|
||||
}
|
||||
}
|
||||
|
||||
//toggle device triggers
|
||||
if(nil != updates[PREF_DEVICE_TRIGGER])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"toggling device notifications");
|
||||
|
||||
//enable device trigger
|
||||
if(YES == [updates[PREF_DEVICE_TRIGGER] boolValue])
|
||||
{
|
||||
//enable
|
||||
[triggers toggle:DEVICE_TRIGGER state:NSOnState];
|
||||
}
|
||||
|
||||
//disable device trigger
|
||||
else
|
||||
{
|
||||
//disable
|
||||
[triggers toggle:DEVICE_TRIGGER state:NSOffState];
|
||||
}
|
||||
}
|
||||
|
||||
//toggle power triggers
|
||||
if(nil != updates[PREF_POWER_TRIGGER])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"toggling power notifications");
|
||||
|
||||
//enable power trigger
|
||||
if(YES == [updates[PREF_POWER_TRIGGER] boolValue])
|
||||
{
|
||||
//enable
|
||||
[triggers toggle:POWER_TRIGGER state:NSOnState];
|
||||
}
|
||||
|
||||
//disable power trigger
|
||||
else
|
||||
{
|
||||
//disable
|
||||
[triggers toggle:POWER_TRIGGER state:NSOffState];
|
||||
}
|
||||
}
|
||||
|
||||
//sync prefs
|
||||
@synchronized(self.preferences)
|
||||
{
|
||||
|
||||
//updating list of registered devices?
|
||||
// it's a dictionary so requires an extra merge
|
||||
if( (nil != updates[PREF_REGISTERED_DEVICES]) &&
|
||||
@@ -221,6 +287,8 @@ bail:
|
||||
//merge
|
||||
[self.preferences addEntriesFromDictionary:updates];
|
||||
}
|
||||
|
||||
}//sync
|
||||
|
||||
//save
|
||||
if(YES != [self save])
|
||||
@@ -244,9 +312,6 @@ bail:
|
||||
// then update preferences with this list...
|
||||
-(void)updateRegisteredDevices
|
||||
{
|
||||
//current devices
|
||||
NSDictionary* currentDevices = nil;
|
||||
|
||||
//client
|
||||
DNDClientMac *client;
|
||||
|
||||
@@ -262,10 +327,9 @@ bail:
|
||||
//alloc dictionary
|
||||
devices = [NSMutableDictionary dictionary];
|
||||
|
||||
//get current devices
|
||||
// aren't any, just bail
|
||||
currentDevices = self.preferences[PREF_REGISTERED_DEVICES];
|
||||
if(0 == currentDevices.count)
|
||||
//aren't any registered devices?
|
||||
// just bail
|
||||
if(0 == [self.preferences[PREF_REGISTERED_DEVICES] count])
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
@@ -305,20 +369,26 @@ bail:
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//sync prefs
|
||||
@synchronized(self.preferences)
|
||||
{
|
||||
|
||||
//get list of registered devices from server
|
||||
// build (updated) list of devices id : device name mappings
|
||||
for(NSString* deviceID in macShadow.state.reported.endpoints)
|
||||
{
|
||||
//sanity check
|
||||
if(nil == currentDevices[deviceID])
|
||||
if(nil == self.preferences[PREF_REGISTERED_DEVICES][deviceID])
|
||||
{
|
||||
//skip
|
||||
continue;
|
||||
}
|
||||
|
||||
//add current device name
|
||||
devices[deviceID] = currentDevices[deviceID];
|
||||
devices[deviceID] = self.preferences[PREF_REGISTERED_DEVICES][deviceID];
|
||||
}
|
||||
|
||||
}//sync
|
||||
|
||||
//no registered devices?
|
||||
// remove key from preferences
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
// file: Triggers.m
|
||||
// project: DND (launch daemon)
|
||||
// description: generic management of various triggers (header)
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Utilities.h"
|
||||
#import "LidTrigger.h"
|
||||
#import "PowerTrigger.h"
|
||||
#import "DeviceTrigger.h"
|
||||
#import <dnd/dnd-Swift.h>
|
||||
|
||||
@import Foundation;
|
||||
|
||||
/* FUNCTIONS */
|
||||
|
||||
//check if user auth'd
|
||||
// a) within last 10 seconds
|
||||
// b) via biometrics (touchID)
|
||||
BOOL authViaTouchID(void);
|
||||
|
||||
/* CLASS INTERFACE */
|
||||
|
||||
@interface Triggers : NSObject <DNDClientMacDelegate>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
//lid trigger obj
|
||||
@property(nonatomic, retain)LidTrigger* lidTrigger;
|
||||
|
||||
//device(s) trigger obj
|
||||
@property(nonatomic, retain)DeviceTrigger* deviceTrigger;
|
||||
|
||||
//power trigger obj
|
||||
@property(nonatomic, retain)PowerTrigger* powerTrigger;
|
||||
|
||||
|
||||
//client
|
||||
@property(nonatomic, retain)DNDClientMac* client;
|
||||
|
||||
//dismiss dispatch group
|
||||
@property(nonatomic, retain)dispatch_group_t dispatchGroup;
|
||||
|
||||
//dispatch group flag
|
||||
@property BOOL dispatchGroupEmpty;
|
||||
|
||||
//dispatch blocks
|
||||
@property(nonatomic, retain)NSMutableArray* dispatchBlocks;
|
||||
|
||||
//TODO: make dictionary w/ alert
|
||||
//latest undeliveried alert
|
||||
@property(nonatomic, retain)NSDate* undeliveredAlert;
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//toggle trigger(s)
|
||||
-(void)toggle:(NSUInteger)type state:(NSControlStateValue)state;
|
||||
|
||||
//check if client should be init'd
|
||||
-(BOOL)shouldInitClient;
|
||||
|
||||
//init dnd client
|
||||
-(BOOL)clientInit;
|
||||
|
||||
//cancel all dipatch blocks
|
||||
-(void)cancelDispatchBlocks;
|
||||
|
||||
//process trigger event
|
||||
-(void)processEvent:(NSUInteger)type info:(NSDictionary*)info;
|
||||
|
||||
//wait for dismiss
|
||||
// note: handles multiple client via dispatch group
|
||||
-(void)wait4Dismiss;
|
||||
|
||||
//execute action
|
||||
-(int)executeAction:(NSString*)path user:(NSString*)user;
|
||||
|
||||
@end
|
||||
@@ -1,19 +1,16 @@
|
||||
// file: Lid.m
|
||||
// file: Triggers.m
|
||||
// project: DND (launch daemon)
|
||||
// description: monitor and alert logic for lid open events
|
||||
// description: generic management of various triggers
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
// code inspired by:
|
||||
// https://github.com/zarigani/ClamshellWake/blob/master/ClamshellWake.cpp
|
||||
// https://github.com/dustinrue/ControlPlane/blob/master/Source/LaptopLidEvidenceSource.m
|
||||
|
||||
// note: manually get state from terminal via:
|
||||
// ioreg -r -k AppleClamshellState -d 4 | grep AppleClamshellState
|
||||
|
||||
#import "Lid.h"
|
||||
#import "Consts.h"
|
||||
#import "Queue.h"
|
||||
#import "Logging.h"
|
||||
#import "Monitor.h"
|
||||
#import "Triggers.h"
|
||||
#import "AuthEvent.h"
|
||||
#import "Utilities.h"
|
||||
#import "Preferences.h"
|
||||
@@ -22,12 +19,8 @@
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
//last state
|
||||
// sometimes multiple notifications are delivered!?
|
||||
LidState lastLidState;
|
||||
|
||||
//lid obj
|
||||
extern Lid* lid;
|
||||
//trigger obj
|
||||
extern Triggers* triggers;
|
||||
|
||||
//queue object
|
||||
extern Queue* eventQueue;
|
||||
@@ -41,123 +34,6 @@ extern Preferences* preferences;
|
||||
//DND framework interface obj
|
||||
extern FrameworkInterface* framework;
|
||||
|
||||
//callback for power/lid events
|
||||
static void pmDomainChange(void *refcon, io_service_t service, uint32_t messageType, void *messageArgument)
|
||||
{
|
||||
//lid state
|
||||
int lidState = stateUnavailable;
|
||||
|
||||
//sleep bit
|
||||
int sleepState = -1;
|
||||
|
||||
//preferences
|
||||
NSDictionary* currentPrefs = nil;
|
||||
|
||||
//timestamp
|
||||
NSDate* timestamp = nil;
|
||||
|
||||
//init timestamp
|
||||
timestamp = [NSDate date];
|
||||
|
||||
//ignore any messages that are related to lid state
|
||||
if(kIOPMMessageClamshellStateChange != messageType)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"got 'kIOPMMessageClamshellStateChange' message");
|
||||
|
||||
//get prefs
|
||||
currentPrefs = [preferences get:nil];
|
||||
|
||||
//if user explicity set disabled
|
||||
// bail here, to ignore everything
|
||||
if(YES == [currentPrefs[PREF_IS_DISABLED] boolValue])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"client disabled DND, so ignoring lid event");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//get state
|
||||
lidState = ((int) messageArgument & kClamshellStateBit);
|
||||
|
||||
//get sleep state
|
||||
sleepState = !!(((int)messageArgument & kClamshellSleepBit));
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"lid state: %@ (sleep bit: %d)", (lidState) ? @"closed" : @"open", sleepState]);
|
||||
|
||||
//(new) open?
|
||||
// OS sometimes delivers 2x events, so ignore same same
|
||||
if( (stateOpen == lidState) &&
|
||||
(stateOpen != lastLidState) )
|
||||
{
|
||||
//ignore if lid isn't really open
|
||||
// on reboot, OS may deliver 'open' message if external monitors are connected
|
||||
if(stateOpen != getLidState())
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//update 'prev' state
|
||||
lastLidState = stateOpen;
|
||||
|
||||
//dbg msg
|
||||
// log to file
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"[NEW EVENT] lid state: open (sleep state: %d)", sleepState]);
|
||||
|
||||
//touch id mode?
|
||||
// wait up to 10 seconds, and ignore event if user auth'd via biometrics
|
||||
if(YES == [currentPrefs[PREF_TOUCHID_MODE] boolValue])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"'touch id' mode enabled, waiting up to 10 seconds for biometric auth event");
|
||||
|
||||
//user auth'd via touchID?
|
||||
// will wait for up to 10 seconds
|
||||
if(YES == authViaTouchID())
|
||||
{
|
||||
//dbg msg
|
||||
// log to file
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, @"user authenticated via touchID, so ignoring event");
|
||||
|
||||
//bail
|
||||
// will ignore the event
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"no touch id auth event found, so will process event");
|
||||
}
|
||||
|
||||
//process event
|
||||
// report to user, execute actions, etc
|
||||
[lid processEvent:timestamp];
|
||||
}
|
||||
|
||||
//(new) close?
|
||||
// OS sometimes delivers 2x events, so ignore same same
|
||||
else if( (stateClosed == lidState) &&
|
||||
(stateClosed != lastLidState) )
|
||||
{
|
||||
//update 'prev' state
|
||||
lastLidState = stateClosed;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"[NEW EVENT] lid state: closed (sleep state: %d)", sleepState]);
|
||||
}
|
||||
|
||||
bail:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//check if user auth'd
|
||||
// a) within last 10 seconds
|
||||
// b) via biometrics (touchID)
|
||||
@@ -230,7 +106,7 @@ BOOL authViaTouchID()
|
||||
});
|
||||
|
||||
//wait for touch id auth
|
||||
// ...up to five seconds
|
||||
// ...up to ten seconds for event
|
||||
dispatch_semaphore_wait(semaphore, dispatch_time(0, 10*NSEC_PER_SEC));
|
||||
|
||||
//tell user auth monitor to stop
|
||||
@@ -242,11 +118,17 @@ BOOL authViaTouchID()
|
||||
return touchIDAuth;
|
||||
}
|
||||
|
||||
@implementation Lid
|
||||
@implementation Triggers
|
||||
|
||||
|
||||
@synthesize client;
|
||||
|
||||
@synthesize lidTrigger;
|
||||
@synthesize powerTrigger;
|
||||
@synthesize deviceTrigger;
|
||||
@synthesize dispatchGroup;
|
||||
@synthesize dispatchBlocks;
|
||||
@synthesize undeliveredAlert;
|
||||
@synthesize dispatchGroupEmpty;
|
||||
|
||||
//init
|
||||
@@ -256,21 +138,15 @@ BOOL authViaTouchID()
|
||||
self = [super init];
|
||||
if(nil != self)
|
||||
{
|
||||
//init
|
||||
dispatchQ = NULL;
|
||||
//init lid (trigger) obj
|
||||
lidTrigger = [[LidTrigger alloc] init];
|
||||
|
||||
//init
|
||||
notificationPort = NULL;
|
||||
//init device (trigger) obj
|
||||
deviceTrigger = [[DeviceTrigger alloc] init];
|
||||
|
||||
//init
|
||||
notification = 0;
|
||||
//init power (trigger) obj
|
||||
powerTrigger = [[PowerTrigger alloc] init];
|
||||
|
||||
//init to current state
|
||||
lastLidState = getLidState();
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"initial lid state: %d", lastLidState]);
|
||||
|
||||
//init dispatch group for dismiss events
|
||||
dispatchGroup = dispatch_group_create();
|
||||
|
||||
@@ -344,164 +220,128 @@ bail:
|
||||
return initialized;
|
||||
}
|
||||
|
||||
//register for notifications
|
||||
-(BOOL)register4Notifications
|
||||
//toggle trigger(s)
|
||||
-(void)toggle:(NSUInteger)type state:(NSControlStateValue)state
|
||||
{
|
||||
//return var
|
||||
BOOL registered = NO;
|
||||
//current prefs
|
||||
NSDictionary* currentPrefs = nil;
|
||||
|
||||
//status var
|
||||
kern_return_t status = kIOReturnError;
|
||||
//dbd msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"toggling trigger (type: %lu, state: %lu)", (unsigned long)type, state]);
|
||||
|
||||
//root domain for power management
|
||||
io_service_t powerManagementRD = MACH_PORT_NULL;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"registering for lid notifications");
|
||||
|
||||
//make sure state is ok
|
||||
if(stateUnavailable == getLidState())
|
||||
//enable based on type
|
||||
switch(type)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to get lid state, so aborting lid notifications registration");
|
||||
//all
|
||||
// based on triggers
|
||||
case ALL_TRIGGERS:
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"toggling all triggers");
|
||||
|
||||
//get current prefs
|
||||
currentPrefs = [preferences get:nil];
|
||||
|
||||
//lid trigger?
|
||||
if(YES == [currentPrefs[PREF_LID_TRIGGER] boolValue])
|
||||
{
|
||||
//toggle
|
||||
[self.lidTrigger toggle:state];
|
||||
}
|
||||
|
||||
//device trigger?
|
||||
if(YES == [currentPrefs[PREF_DEVICE_TRIGGER] boolValue])
|
||||
{
|
||||
//toggle
|
||||
[self.deviceTrigger toggle:state];
|
||||
}
|
||||
|
||||
//power trigger
|
||||
if(YES == [currentPrefs[PREF_POWER_TRIGGER] boolValue])
|
||||
{
|
||||
//toggle
|
||||
[self.powerTrigger toggle:state];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//lid trigger
|
||||
case LID_TRIGGER:
|
||||
|
||||
//toggle
|
||||
[self.lidTrigger toggle:state];
|
||||
|
||||
break;
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
//device trigger
|
||||
case DEVICE_TRIGGER:
|
||||
|
||||
//toggle
|
||||
[self.deviceTrigger toggle:state];
|
||||
|
||||
break;
|
||||
|
||||
//power trigger
|
||||
case POWER_TRIGGER:
|
||||
|
||||
//toggle
|
||||
[self.powerTrigger toggle:state];
|
||||
|
||||
break;
|
||||
|
||||
//create queue
|
||||
dispatchQ = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
|
||||
if(NULL == dispatchQ)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to create dispatch queue for lid notifications");
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//set target
|
||||
dispatch_set_target_queue(dispatchQ, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0));
|
||||
|
||||
//create notification port
|
||||
notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
|
||||
if(NULL == notificationPort)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to create notification port for lid notifications");
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//set dispatch queue
|
||||
IONotificationPortSetDispatchQueue(notificationPort, dispatchQ);
|
||||
|
||||
//get matching service for power management root domain
|
||||
powerManagementRD = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPMrootDomain"));
|
||||
if(0 == powerManagementRD)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to get power management root domain for lid notifications");
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//add interest notification
|
||||
status = IOServiceAddInterestNotification(notificationPort, powerManagementRD, kIOGeneralInterest,
|
||||
pmDomainChange, &lidState, ¬ification);
|
||||
if(KERN_SUCCESS != status)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to get add interest notifcation for lid notifications (error: 0x:%x)", status]);
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//happy
|
||||
registered = YES;
|
||||
|
||||
bail:
|
||||
|
||||
//release
|
||||
if(MACH_PORT_NULL != powerManagementRD)
|
||||
{
|
||||
//release
|
||||
IOObjectRelease(powerManagementRD);
|
||||
|
||||
//unset
|
||||
powerManagementRD = MACH_PORT_NULL;
|
||||
}
|
||||
|
||||
return registered;
|
||||
}
|
||||
|
||||
//unregister for notifications
|
||||
-(void)unregister4Notifications
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"unregistering lid notifications");
|
||||
|
||||
//release notification
|
||||
if(0 != notification)
|
||||
{
|
||||
//release
|
||||
IOObjectRelease(notification);
|
||||
|
||||
//unset
|
||||
notification = 0;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"released service interest notification");
|
||||
}
|
||||
|
||||
//destroy notification port
|
||||
if(NULL != notificationPort)
|
||||
{
|
||||
//set queue to NULL
|
||||
IONotificationPortSetDispatchQueue(notificationPort, NULL);
|
||||
|
||||
//unset dispatch queue
|
||||
dispatchQ = NULL;
|
||||
|
||||
//destroy port
|
||||
IONotificationPortDestroy(notificationPort);
|
||||
|
||||
//unset
|
||||
notificationPort = NULL;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"destroyed notification port");
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//proces lid open event
|
||||
//proces trigger event
|
||||
// report to user, execute cmd, send alert to server, etc
|
||||
-(void)processEvent:(NSDate*)timestamp
|
||||
-(void)processEvent:(NSUInteger)type info:(NSDictionary*)info
|
||||
{
|
||||
//monitor obj
|
||||
Monitor* monitor = nil;
|
||||
|
||||
//console user
|
||||
NSString* consoleUser = nil;
|
||||
|
||||
|
||||
//current prefs
|
||||
NSDictionary* currentPrefs = nil;
|
||||
|
||||
//get current prefs
|
||||
currentPrefs = [preferences get:nil];
|
||||
|
||||
//auth mode?
|
||||
// wait up to 10 seconds, and ignore event if user auth'd via biometrics or apple watch
|
||||
if(YES == [currentPrefs[PREF_AUTH_MODE] boolValue])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"'auth' mode enabled, waiting up to 10 seconds for biometric auth || apple watch event");
|
||||
|
||||
//TODO: add apple watch
|
||||
|
||||
//user auth'd via touchID?
|
||||
// will wait for up to 10 seconds
|
||||
if(YES == authViaTouchID())
|
||||
{
|
||||
//dbg msg
|
||||
// log to file
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, @"user authenticated via touchID, so ignoring event");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"no touch id auth event found, so will continue processing event");
|
||||
}
|
||||
|
||||
//only add events to queue
|
||||
// when client is not running in passive mode
|
||||
if(YES != [currentPrefs[PREF_PASSIVE_MODE] boolValue])
|
||||
{
|
||||
//add to global queue
|
||||
// this will trigger processing of alert to user
|
||||
[eventQueue enqueue:@{ALERT_TIMESTAMP:timestamp}];
|
||||
[eventQueue enqueue:@{ALERT_TYPE:[NSNumber numberWithInteger:type], ALERT_TIMESTAMP:[NSDate date], ALERT_INFO:info}];
|
||||
}
|
||||
//passive mode
|
||||
// just log a msg about this fact
|
||||
@@ -534,7 +374,6 @@ bail:
|
||||
if( (YES == [currentPrefs[PREF_EXECUTE_ACTION] boolValue]) &&
|
||||
(0 != [currentPrefs[PREF_EXECUTE_PATH] length] ) )
|
||||
{
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"executing: %@ as %@", currentPrefs[PREF_EXECUTE_PATH], currentPrefs[PREF_EXECUTE_USER]]);
|
||||
|
||||
@@ -565,41 +404,43 @@ bail:
|
||||
logMsg(LOG_DEBUG, @"(re)initialized DND client for framework");
|
||||
}
|
||||
|
||||
//send to server
|
||||
// and wait for dismiss
|
||||
//registered device?
|
||||
// send alert to server
|
||||
if(nil != self.client)
|
||||
{
|
||||
//get user
|
||||
consoleUser = getConsoleUser();
|
||||
if(0 == consoleUser.length)
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"found registerd device/client, will try send alert to server");
|
||||
|
||||
//no undelivered alert?
|
||||
// spawn off dispatch to deliver
|
||||
if(nil == self.undeliveredAlert)
|
||||
{
|
||||
//defult
|
||||
consoleUser = @"unknown";
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"no (prev) alerts undelivered");
|
||||
|
||||
//save timestamp
|
||||
self.undeliveredAlert = [NSDate date];
|
||||
|
||||
//send to server
|
||||
// will wait up to x minutes if there's no network connectivity
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
//wait
|
||||
[self send2Server:getConsoleUser()];
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
// and log to file
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"sending alert to server (user: %@)", consoleUser]);
|
||||
|
||||
//send
|
||||
[self.client sendAlertWithUuid:[NSUUID UUID] userName:consoleUser date:timestamp completion:^(NSNumber* response)
|
||||
//already send(ing) alert
|
||||
// just update, so if network comes online, will use this one (as latest)
|
||||
else
|
||||
{
|
||||
//log
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"response from server: %@", response]);
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"previously alert undelivered, just updating that...");
|
||||
|
||||
//after getting server response
|
||||
// update list of registered devices...
|
||||
[preferences updateRegisteredDevices];
|
||||
|
||||
}];
|
||||
|
||||
//wait for dismiss
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
//wait
|
||||
[self wait4Dismiss];
|
||||
|
||||
});
|
||||
//save timestamp
|
||||
self.undeliveredAlert = [NSDate date];
|
||||
}
|
||||
}
|
||||
|
||||
//didn't send
|
||||
@@ -607,7 +448,7 @@ bail:
|
||||
else
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"did not send to server - no client/registered device");
|
||||
logMsg(LOG_DEBUG, @"did not send to server, as there's no client/registered device");
|
||||
}
|
||||
|
||||
bail:
|
||||
@@ -615,6 +456,94 @@ bail:
|
||||
return;
|
||||
}
|
||||
|
||||
//send alert to server
|
||||
// contains extra logic to check/wait for network connectivty
|
||||
-(void)send2Server:(NSString*)user
|
||||
{
|
||||
//flag
|
||||
BOOL sent = NO;
|
||||
|
||||
//response
|
||||
__block NSNumber* response = nil;
|
||||
|
||||
//no user?
|
||||
// set to default, but will try again
|
||||
if(0 == user.length)
|
||||
{
|
||||
//default
|
||||
user = USER_UNKNOWN;
|
||||
}
|
||||
|
||||
//try send up to 10 times
|
||||
// basically gives time for network to reconnect if lid-shut disconnected wifi, etc...
|
||||
for(NSUInteger i=0; i<10; i++)
|
||||
{
|
||||
//unknown user?
|
||||
// try get user again
|
||||
if(YES == [user isEqualToString:USER_UNKNOWN])
|
||||
{
|
||||
//get user
|
||||
user = getConsoleUser();
|
||||
if(0 == user.length)
|
||||
{
|
||||
//default
|
||||
user = USER_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
// and log to file
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"sending alert to server (user: %@)", user]);
|
||||
|
||||
//send
|
||||
response = [self.client sendAlertSyncWithUuid:[NSUUID UUID] userName:user date:self.undeliveredAlert];
|
||||
if(nil != response)
|
||||
{
|
||||
//log
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"response from server: %@", response]);
|
||||
|
||||
//after getting server response
|
||||
// update list of registered devices
|
||||
[preferences updateRegisteredDevices];
|
||||
|
||||
//set flag
|
||||
sent = YES;
|
||||
|
||||
//wait for dismiss
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
//wait
|
||||
[self wait4Dismiss];
|
||||
|
||||
});
|
||||
|
||||
//done
|
||||
break;
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"could not reach endpoint - network offline?");
|
||||
|
||||
//not online
|
||||
//... so tak a nap
|
||||
[NSThread sleepForTimeInterval:i*1.5];
|
||||
}
|
||||
|
||||
//check
|
||||
// log err
|
||||
if(YES != sent)
|
||||
{
|
||||
//log
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, @"unable to deliver alert (network offline?)");
|
||||
}
|
||||
|
||||
//unset
|
||||
// even if we failed to send
|
||||
self.undeliveredAlert = nil;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//wait for dismiss
|
||||
// note: handles multiple client via dispatch group
|
||||
-(void)wait4Dismiss
|
||||
@@ -754,7 +683,7 @@ bail:
|
||||
int result = -1;
|
||||
|
||||
//exec script
|
||||
// su man -c <user> <path>
|
||||
// su -c <user> <path>
|
||||
results = execTask(@"/usr/bin/su", @[user, @"-c", path], YES);
|
||||
|
||||
//dbg msg
|
||||
@@ -7,6 +7,8 @@
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
@import Foundation;
|
||||
|
||||
/* FUNCTIONS */
|
||||
|
||||
//uninstall
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Lid.h"
|
||||
#import "main.h"
|
||||
#import "Consts.h"
|
||||
#import "Queue.h"
|
||||
#import "Consts.h"
|
||||
#import "Logging.h"
|
||||
#import "Triggers.h"
|
||||
#import "Utilities.h"
|
||||
#import "Preferences.h"
|
||||
#import "UserAuthMonitor.h"
|
||||
@@ -27,7 +27,7 @@ Preferences* preferences = nil;
|
||||
|
||||
//lid object
|
||||
// registers for notifications, gets state, etc
|
||||
Lid* lid = nil;
|
||||
Triggers* triggers = nil;
|
||||
|
||||
//queue object
|
||||
// contains watch items that should be processed
|
||||
@@ -48,7 +48,7 @@ int main(int argc, const char * argv[])
|
||||
{
|
||||
//return
|
||||
int result = -1;
|
||||
|
||||
|
||||
@autoreleasepool
|
||||
{
|
||||
//user comms listener (XPC) obj
|
||||
@@ -123,6 +123,7 @@ int main(int argc, const char * argv[])
|
||||
// allows to close logging, etc.
|
||||
register4Shutdown();
|
||||
|
||||
|
||||
//1st time identity generatation is done on demand
|
||||
// subsequent times though, can just always do here
|
||||
if(nil != currentPrefs[PREF_CLIENT_ID])
|
||||
@@ -141,30 +142,27 @@ int main(int argc, const char * argv[])
|
||||
logMsg(LOG_DEBUG, @"initialized DND identity");
|
||||
}
|
||||
|
||||
//init global lid object
|
||||
lid = [[Lid alloc] init];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"lid state: %d", getLidState()]);
|
||||
//init global triggers object
|
||||
triggers = [[Triggers alloc] init];
|
||||
|
||||
//not (prev) disabled?
|
||||
// register for lid notifications
|
||||
// toggle all triggers based on their setting
|
||||
if(YES != [currentPrefs[PREF_IS_DISABLED] boolValue])
|
||||
{
|
||||
//register for lid notifications
|
||||
[lid register4Notifications];
|
||||
//toggle all triggers
|
||||
[triggers toggle:ALL_TRIGGERS state:NSOnState];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"registered for lid change notifications");
|
||||
logMsg(LOG_DEBUG, @"toggled (all) triggers");
|
||||
}
|
||||
|
||||
//(prev) disabled
|
||||
else
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"currently disabled, so did not register for lid change notifications");
|
||||
logMsg(LOG_DEBUG, @"user set 'disabled' preference, so did not register for any triggers");
|
||||
}
|
||||
|
||||
|
||||
//init global queue
|
||||
eventQueue = [[Queue alloc] init];
|
||||
|
||||
@@ -185,9 +183,6 @@ int main(int argc, const char * argv[])
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"listening for client XPC connections");
|
||||
|
||||
//run loop
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
|
||||
}//pool
|
||||
|
||||
//happy
|
||||
|
||||
@@ -18,23 +18,23 @@
|
||||
// note: will only detect files downloaded from apps such as browsers (that have 'kMDItemWhereFroms' key set)
|
||||
-(void)start
|
||||
{
|
||||
//has to be run on the main thread!
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
//alloc/init query
|
||||
query = [[NSMetadataQuery alloc] init];
|
||||
|
||||
//add observer
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDownloadEvent:) name:NSMetadataQueryDidUpdateNotification object:query];
|
||||
//has to be run on the main thread!
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
//add observer
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDownloadEvent:) name:NSMetadataQueryDidUpdateNotification object:self.query];
|
||||
|
||||
//set delegate
|
||||
self.query.delegate = self;
|
||||
//set delegate
|
||||
self.query.delegate = self;
|
||||
|
||||
//set predicate
|
||||
self.query.predicate = [NSPredicate predicateWithFormat:@"%K like '*'", @"kMDItemWhereFroms"];
|
||||
//set predicate
|
||||
self.query.predicate = [NSPredicate predicateWithFormat:@"%K like '*'", @"kMDItemWhereFroms"];
|
||||
|
||||
//start
|
||||
[query startQuery];
|
||||
//start
|
||||
[self.query startQuery];
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// file: DeviceTrigger.h
|
||||
// project: DND (launch daemon)
|
||||
// description: monitor and alert logic for device insertion events (header)
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
@import Cocoa;
|
||||
@import Foundation;
|
||||
|
||||
#import <IOKit/usb/IOUSBLib.h>
|
||||
|
||||
/* CLASS INTERFACE */
|
||||
|
||||
@interface DeviceTrigger : NSObject
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
//notification port
|
||||
@property(nonatomic)IONotificationPortRef notificationPort;
|
||||
|
||||
//callback for USB devices
|
||||
void usbAppeared(void *refCon, io_iterator_t iterator);
|
||||
|
||||
//run loop source
|
||||
@property(nonatomic)CFRunLoopSourceRef runLoopSource;
|
||||
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//register for notifications
|
||||
-(BOOL)toggle:(NSControlStateValue)state;
|
||||
|
||||
//process new USB insertion
|
||||
// get info about device and log
|
||||
-(void)handleNewDevice:(io_iterator_t)iterator;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,244 @@
|
||||
// file: DeviceTrigger.m
|
||||
// project: DND (launch daemon)
|
||||
// description: monitor and alert logic for device insertion events
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Consts.h"
|
||||
#import "Logging.h"
|
||||
#import "Triggers.h"
|
||||
#import "Utilities.h"
|
||||
#import "Preferences.h"
|
||||
#import "DeviceTrigger.h"
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
//triggers object
|
||||
extern Triggers* triggers;
|
||||
|
||||
//preferences obj
|
||||
extern Preferences* preferences;
|
||||
|
||||
@implementation DeviceTrigger
|
||||
|
||||
@synthesize runLoopSource;
|
||||
@synthesize notificationPort;
|
||||
|
||||
//callback for USB devices
|
||||
void usbAppeared(void *refCon, io_iterator_t iterator)
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"usb device inserted"]);
|
||||
|
||||
//process new device
|
||||
[(__bridge DeviceTrigger *)refCon handleNewDevice:iterator];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//toggle lid notifications
|
||||
-(BOOL)toggle:(NSControlStateValue)state
|
||||
{
|
||||
//flag
|
||||
BOOL wasToggled = NO;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"toggling devices notifications: %lu", state]);
|
||||
|
||||
//on?
|
||||
// enable
|
||||
if(NSOnState == state)
|
||||
{
|
||||
//enable
|
||||
wasToggled = [self enable];
|
||||
}
|
||||
//off
|
||||
// disable
|
||||
else
|
||||
{
|
||||
//disable
|
||||
[self disable];
|
||||
|
||||
//manually set flag
|
||||
wasToggled = YES;
|
||||
}
|
||||
|
||||
return wasToggled;
|
||||
}
|
||||
|
||||
//start USB monitoring
|
||||
-(BOOL)enable
|
||||
{
|
||||
//status
|
||||
BOOL initialized = NO;
|
||||
|
||||
//status
|
||||
kern_return_t status = kIOReturnError;
|
||||
|
||||
//iterator
|
||||
io_iterator_t iterator = 0;
|
||||
|
||||
//device
|
||||
io_service_t device = 0;
|
||||
|
||||
//create notification port
|
||||
self.notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
|
||||
|
||||
//get run loop source
|
||||
self.runLoopSource = IONotificationPortGetRunLoopSource(self.notificationPort);
|
||||
|
||||
//add source
|
||||
CFRunLoopAddSource(CFRunLoopGetMain(), runLoopSource, kCFRunLoopDefaultMode);
|
||||
|
||||
//add notification
|
||||
// pass in 'self' so can access obj-c methods in callbacks
|
||||
status = IOServiceAddMatchingNotification(self.notificationPort, kIOMatchedNotification, IOServiceMatching(kIOUSBDeviceClassName), usbAppeared,(__bridge void *)self, &iterator);
|
||||
if(kIOReturnSuccess != status)
|
||||
{
|
||||
//err
|
||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"IOServiceAddMatchingNotification() failed with %d", status]);
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//process existing devices
|
||||
// also 'drains' interator...
|
||||
device = IOIteratorNext(iterator);
|
||||
while(0 != device)
|
||||
{
|
||||
//record device name/properties
|
||||
//[self logDeviceProperties:device];
|
||||
|
||||
//release
|
||||
IOObjectRelease(device);
|
||||
|
||||
//get next
|
||||
device = IOIteratorNext(iterator);
|
||||
}
|
||||
|
||||
//happy
|
||||
initialized = YES;
|
||||
|
||||
bail:
|
||||
|
||||
return initialized;
|
||||
}
|
||||
|
||||
//stop
|
||||
// invalidate runloop src and notification port
|
||||
-(void)disable
|
||||
{
|
||||
//invalidate runloop src
|
||||
if(nil != self.runLoopSource)
|
||||
{
|
||||
//invalidate
|
||||
CFRunLoopSourceInvalidate(self.runLoopSource);
|
||||
|
||||
//unset
|
||||
self.runLoopSource = nil;
|
||||
}
|
||||
|
||||
//destroy notification port
|
||||
if(nil != self.notificationPort)
|
||||
{
|
||||
//destroy
|
||||
IONotificationPortDestroy(self.notificationPort);
|
||||
|
||||
//unset
|
||||
self.notificationPort = nil;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//process new USB insertion
|
||||
// get info about device and log
|
||||
-(void)handleNewDevice:(io_iterator_t)iterator
|
||||
{
|
||||
//usb device
|
||||
io_service_t device;
|
||||
|
||||
//device name
|
||||
io_name_t deviceName = {0};
|
||||
|
||||
//timestamp
|
||||
NSDate* timestamp = nil;
|
||||
|
||||
//process
|
||||
while((device = IOIteratorNext(iterator)))
|
||||
{
|
||||
//reset
|
||||
bzero(deviceName, sizeof(io_name_t));
|
||||
|
||||
//init timestamp
|
||||
timestamp = [NSDate date];
|
||||
|
||||
//get device name
|
||||
if(KERN_SUCCESS != IORegistryEntryGetName(device, deviceName))
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to get usb device name");
|
||||
|
||||
//set to unknown
|
||||
strncpy(deviceName, "<unknown>", sizeof(io_name_t)-1);
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
// log to file
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"[NEW EVENT] usb inserted: \"%s\"", deviceName]);
|
||||
|
||||
//process event
|
||||
// report to user, server, execute actions, etc.
|
||||
[triggers processEvent:DEVICE_TRIGGER info:@{KEY_DEVICE_NAME:[NSString stringWithUTF8String:deviceName]}];
|
||||
|
||||
//release device
|
||||
IOObjectRelease(device);
|
||||
|
||||
//unset
|
||||
device = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//log name/properties of a device
|
||||
-(void)logDeviceProperties:(io_service_t)device
|
||||
{
|
||||
//device name
|
||||
io_name_t deviceName = {0};
|
||||
|
||||
//device properties
|
||||
CFMutableDictionaryRef deviceProperties = NULL;
|
||||
|
||||
//get device name
|
||||
if(KERN_SUCCESS == IORegistryEntryGetName(device, deviceName))
|
||||
{
|
||||
//dbg msg & log
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"usb device name: %s", deviceName]);
|
||||
}
|
||||
|
||||
//get device properties
|
||||
if( (kIOReturnSuccess == IORegistryEntryCreateCFProperties(device, &deviceProperties, kCFAllocatorDefault, kNilOptions)) &&
|
||||
(NULL != deviceProperties) )
|
||||
{
|
||||
//dbg msg & log
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"usb device properties: %@", deviceProperties]);
|
||||
}
|
||||
|
||||
//release device props
|
||||
if(NULL != deviceProperties)
|
||||
{
|
||||
//release
|
||||
CFRelease(deviceProperties);
|
||||
|
||||
//unset
|
||||
deviceProperties = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// file: LidTrigger.h
|
||||
// project: DND (launch daemon)
|
||||
// description: monitor and alert logic for lid open events (header)
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Utilities.h"
|
||||
|
||||
@import Foundation;
|
||||
|
||||
#import <IOKit/IOKitLib.h>
|
||||
#import <IOKit/pwr_mgt/IOPM.h>
|
||||
|
||||
|
||||
/* CLASS INTERFACE */
|
||||
|
||||
@interface LidTrigger : NSObject
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
//lid state
|
||||
@property LidState lidState;
|
||||
|
||||
//dispatch queue
|
||||
@property dispatch_queue_t dispatchQ;
|
||||
|
||||
//notification port
|
||||
@property IONotificationPortRef notificationPort;
|
||||
|
||||
//notification object
|
||||
@property io_object_t notification;
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//register for notifications
|
||||
-(BOOL)toggle:(NSControlStateValue)state;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,325 @@
|
||||
// file: LidTrigger.m
|
||||
// project: DND (launch daemon)
|
||||
// description: monitor and alert logic for lid open events
|
||||
|
||||
// code inspired by:
|
||||
// https://github.com/zarigani/ClamshellWake/blob/master/ClamshellWake.cpp
|
||||
// https://github.com/dustinrue/ControlPlane/blob/master/Source/LaptopLidEvidenceSource.m
|
||||
|
||||
// note: manually get state from terminal via:
|
||||
// ioreg -r -k AppleClamshellState -d 4 | grep AppleClamshellState
|
||||
|
||||
#import "Consts.h"
|
||||
#import "Logging.h"
|
||||
#import "Triggers.h"
|
||||
#import "Utilities.h"
|
||||
#import "LidTrigger.h"
|
||||
#import "Preferences.h"
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
//last state
|
||||
// sometimes multiple notifications are delivered!?
|
||||
LidState lastLidState;
|
||||
|
||||
//triggers object
|
||||
extern Triggers* triggers;
|
||||
|
||||
//preferences obj
|
||||
extern Preferences* preferences;
|
||||
|
||||
//callback for power/lid events
|
||||
static void pmDomainChange(void *refcon, io_service_t service, uint32_t messageType, void *messageArgument)
|
||||
{
|
||||
//lid state
|
||||
int lidState = stateUnavailable;
|
||||
|
||||
//sleep bit
|
||||
int sleepState = -1;
|
||||
|
||||
//preferences
|
||||
NSDictionary* currentPrefs = nil;
|
||||
|
||||
//timestamp
|
||||
NSDate* timestamp = nil;
|
||||
|
||||
//init timestamp
|
||||
timestamp = [NSDate date];
|
||||
|
||||
//ignore any messages that are related to lid state
|
||||
if(kIOPMMessageClamshellStateChange != messageType)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"got 'kIOPMMessageClamshellStateChange' message");
|
||||
|
||||
//get prefs
|
||||
currentPrefs = [preferences get:nil];
|
||||
|
||||
//if user explicity set disabled
|
||||
// bail here, to ignore everything
|
||||
if(YES == [currentPrefs[PREF_IS_DISABLED] boolValue])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"client disabled DND, so ignoring lid event");
|
||||
|
||||
//update 'prev' state?
|
||||
lastLidState = stateOpen;
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//get state
|
||||
lidState = ((int) messageArgument & kClamshellStateBit);
|
||||
|
||||
//get sleep state
|
||||
sleepState = !!(((int)messageArgument & kClamshellSleepBit));
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"lid state: %@ (sleep bit: %d)", (lidState) ? @"closed" : @"open", sleepState]);
|
||||
|
||||
//(new) open?
|
||||
// OS sometimes delivers 2x events, so ignore same same
|
||||
if( (stateOpen == lidState) &&
|
||||
(stateOpen != lastLidState) )
|
||||
{
|
||||
//ignore if lid isn't really open
|
||||
// on reboot, OS may deliver 'open' message if external monitors are connected
|
||||
if(stateOpen != getLidState())
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//update 'prev' state
|
||||
lastLidState = stateOpen;
|
||||
|
||||
//dbg msg
|
||||
// log to file
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"[NEW EVENT] lid state: open (sleep state: %d)", sleepState]);
|
||||
|
||||
//process event
|
||||
// report to user, server, execute actions, etc.
|
||||
[triggers processEvent:LID_TRIGGER info:nil];
|
||||
}
|
||||
|
||||
//(new) close?
|
||||
// OS sometimes delivers 2x events, so ignore same same
|
||||
else if( (stateClosed == lidState) &&
|
||||
(stateClosed != lastLidState) )
|
||||
{
|
||||
//update 'prev' state
|
||||
lastLidState = stateClosed;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"[NEW EVENT] lid state: closed (sleep state: %d)", sleepState]);
|
||||
}
|
||||
|
||||
bail:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@implementation LidTrigger
|
||||
|
||||
@synthesize lidState;
|
||||
@synthesize dispatchQ;
|
||||
@synthesize notification;
|
||||
@synthesize notificationPort;
|
||||
|
||||
//init
|
||||
-(id)init
|
||||
{
|
||||
//super
|
||||
self = [super init];
|
||||
if(nil != self)
|
||||
{
|
||||
//init
|
||||
notificationPort = NULL;
|
||||
|
||||
//init
|
||||
notification = 0;
|
||||
|
||||
//init to current state
|
||||
lastLidState = getLidState();
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"initial lid state: %d", lastLidState]);
|
||||
|
||||
//init
|
||||
dispatchQ = NULL;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
//toggle lid notifications
|
||||
-(BOOL)toggle:(NSControlStateValue)state
|
||||
{
|
||||
//flag
|
||||
BOOL wasToggled = NO;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"toggling lid notifications: %lu", state]);
|
||||
|
||||
//on?
|
||||
// enable
|
||||
if(NSOnState == state)
|
||||
{
|
||||
//enable
|
||||
wasToggled = [self enable];
|
||||
}
|
||||
//off
|
||||
// disable
|
||||
else
|
||||
{
|
||||
//disable
|
||||
[self disable];
|
||||
|
||||
//manually set flag
|
||||
wasToggled = YES;
|
||||
}
|
||||
|
||||
return wasToggled;
|
||||
}
|
||||
|
||||
//register for notifications
|
||||
-(BOOL)enable
|
||||
{
|
||||
//return var
|
||||
BOOL registered = NO;
|
||||
|
||||
//status var
|
||||
kern_return_t status = kIOReturnError;
|
||||
|
||||
//root domain for power management
|
||||
io_service_t powerManagementRD = MACH_PORT_NULL;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"registering for lid notifications");
|
||||
|
||||
//make sure state is ok
|
||||
if(stateUnavailable == getLidState())
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to get lid state, so aborting lid notifications registration");
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//create queue
|
||||
dispatchQ = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
|
||||
if(NULL == dispatchQ)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to create dispatch queue for lid notifications");
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//set target
|
||||
dispatch_set_target_queue(dispatchQ, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0));
|
||||
|
||||
//create notification port
|
||||
notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
|
||||
if(NULL == notificationPort)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to create notification port for lid notifications");
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//set dispatch queue
|
||||
IONotificationPortSetDispatchQueue(notificationPort, dispatchQ);
|
||||
|
||||
//get matching service for power management root domain
|
||||
powerManagementRD = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPMrootDomain"));
|
||||
if(0 == powerManagementRD)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to get power management root domain for lid notifications");
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//add interest notification
|
||||
status = IOServiceAddInterestNotification(notificationPort, powerManagementRD, kIOGeneralInterest,
|
||||
pmDomainChange, &lidState, ¬ification);
|
||||
if(KERN_SUCCESS != status)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to get add interest notifcation for lid notifications (error: 0x:%x)", status]);
|
||||
|
||||
//error
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//happy
|
||||
registered = YES;
|
||||
|
||||
bail:
|
||||
|
||||
//release
|
||||
if(MACH_PORT_NULL != powerManagementRD)
|
||||
{
|
||||
//release
|
||||
IOObjectRelease(powerManagementRD);
|
||||
|
||||
//unset
|
||||
powerManagementRD = MACH_PORT_NULL;
|
||||
}
|
||||
|
||||
return registered;
|
||||
}
|
||||
|
||||
//unregister for notifications
|
||||
-(void)disable
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"unregistering lid notifications");
|
||||
|
||||
//release notification
|
||||
if(0 != notification)
|
||||
{
|
||||
//release
|
||||
IOObjectRelease(notification);
|
||||
|
||||
//unset
|
||||
notification = 0;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"released service interest notification");
|
||||
}
|
||||
|
||||
//destroy notification port
|
||||
if(NULL != notificationPort)
|
||||
{
|
||||
//set queue to NULL
|
||||
IONotificationPortSetDispatchQueue(notificationPort, NULL);
|
||||
|
||||
//unset dispatch queue
|
||||
dispatchQ = NULL;
|
||||
|
||||
//destroy port
|
||||
IONotificationPortDestroy(notificationPort);
|
||||
|
||||
//unset
|
||||
notificationPort = NULL;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"destroyed notification port");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// file: Power.m
|
||||
// project: DND (launch daemon)
|
||||
// description: monitor and alert logic for power events (header)
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
@import Cocoa;
|
||||
@import Foundation;
|
||||
|
||||
#import <IOKit/usb/IOUSBLib.h>
|
||||
|
||||
/* CLASS INTERFACE */
|
||||
|
||||
@interface PowerTrigger : NSObject
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
//observer for screensaver off events
|
||||
@property(nonatomic, retain)id screenSaverNotification;
|
||||
|
||||
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//register for notifications
|
||||
-(BOOL)toggle:(NSControlStateValue)state;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,118 @@
|
||||
// file: Power.m
|
||||
// project: DND (launch daemon)
|
||||
// description: monitor and alert logic for power events (header)
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2018 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Consts.h"
|
||||
#import "Logging.h"
|
||||
#import "Triggers.h"
|
||||
#import "Utilities.h"
|
||||
#import "Preferences.h"
|
||||
#import "PowerTrigger.h"
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
//triggers object
|
||||
extern Triggers* triggers;
|
||||
|
||||
//preferences obj
|
||||
extern Preferences* preferences;
|
||||
|
||||
@implementation PowerTrigger
|
||||
|
||||
@synthesize screenSaverNotification;
|
||||
|
||||
|
||||
//toggle lid notifications
|
||||
-(BOOL)toggle:(NSControlStateValue)state
|
||||
{
|
||||
//flag
|
||||
BOOL wasToggled = NO;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"toggling power notifications: %lu", state]);
|
||||
|
||||
//on?
|
||||
// enable
|
||||
if(NSOnState == state)
|
||||
{
|
||||
//enable
|
||||
wasToggled = [self enable];
|
||||
}
|
||||
//off
|
||||
// disable
|
||||
else
|
||||
{
|
||||
//disable
|
||||
[self disable];
|
||||
|
||||
//manually set flag
|
||||
wasToggled = YES;
|
||||
}
|
||||
|
||||
return wasToggled;
|
||||
}
|
||||
|
||||
//start power event monitoring
|
||||
-(BOOL)enable
|
||||
{
|
||||
//status
|
||||
BOOL initialized = NO;
|
||||
|
||||
/*
|
||||
com.apple.screensaver.didstart
|
||||
com.apple.screensaver.willstop
|
||||
com.apple.screensaver.didstop
|
||||
|
||||
*/
|
||||
|
||||
//add observer for screen save on
|
||||
// we don't get a screen save stop, so this will trigger process monitoring for exit of ScreenSaverEngine
|
||||
self.screenSaverNotification = [[NSDistributedNotificationCenter defaultCenter] addObserverForName:@"com.apple.screensaver.didlaunch" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
|
||||
{
|
||||
//TODO: trigger process monitoring
|
||||
|
||||
//dbg msg
|
||||
// log to file
|
||||
//logMsg(LOG_DEBUG|LOG_TO_FILE, @"[NEW EVENT] screen saver did stop");
|
||||
|
||||
//process event
|
||||
// report to user, server, execute actions, etc.
|
||||
//[triggers processEvent:POWER_TRIGGER info:@{KEY_POWER_TYPE:@"screen saver did stop"}];
|
||||
|
||||
}];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"enabled screen saver 'did launch'");
|
||||
|
||||
|
||||
bail:
|
||||
|
||||
return initialized;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//disable
|
||||
-(void)disable
|
||||
{
|
||||
//disable
|
||||
// screen saver start notification
|
||||
if(nil != self.screenSaverNotification)
|
||||
{
|
||||
//remove
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self.screenSaverNotification];
|
||||
|
||||
//unset
|
||||
self.screenSaverNotification = nil;
|
||||
}
|
||||
|
||||
//TODO: make sure to stop process monitoring, if it's still going
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -233,7 +233,7 @@
|
||||
7D7755DB1F02E05B00D0017D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 0930;
|
||||
ORGANIZATIONNAME = "Objective-See";
|
||||
TargetAttributes = {
|
||||
7D7755E21F02E05B00D0017D = {
|
||||
@@ -345,6 +345,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@@ -352,6 +353,7 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@@ -398,6 +400,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@@ -405,6 +408,7 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@@ -447,6 +451,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd.helper";
|
||||
PRODUCT_NAME = "Do Not Disturb Helper";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -467,6 +472,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd.helper";
|
||||
PRODUCT_NAME = "Do Not Disturb Helper";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -38,10 +38,6 @@
|
||||
// call daemon and block, then display, and repeat!
|
||||
while(YES)
|
||||
{
|
||||
//pool
|
||||
@autoreleasepool
|
||||
{
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"requesting alert(s) from daemon, will block");
|
||||
|
||||
@@ -84,8 +80,6 @@
|
||||
//wait for alert to be received
|
||||
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
||||
|
||||
}//pool
|
||||
|
||||
}//forevers
|
||||
|
||||
return;
|
||||
@@ -186,7 +180,29 @@
|
||||
notification.title = @"⚠️ Do Not Disturb Alert";
|
||||
|
||||
//set subtitle
|
||||
notification.subtitle = [NSString stringWithFormat:@"Lid Opened: %@", [dateFormat stringFromDate:alert[ALERT_TIMESTAMP]]];
|
||||
// based on trigger type (lid, usb, etc.)
|
||||
switch([alert[ALERT_TYPE] integerValue])
|
||||
{
|
||||
//lid
|
||||
case LID_TRIGGER:
|
||||
notification.subtitle = [NSString stringWithFormat:@"Lid Opened: %@", [dateFormat stringFromDate:alert[ALERT_TIMESTAMP]]];
|
||||
break;
|
||||
|
||||
//device
|
||||
case DEVICE_TRIGGER:
|
||||
notification.subtitle = [NSString stringWithFormat:@"Device Inserted: %@", alert[ALERT_INFO][KEY_DEVICE_NAME]];
|
||||
break;
|
||||
|
||||
//power
|
||||
case POWER_TRIGGER:
|
||||
notification.subtitle = [NSString stringWithFormat:@"Power Event: %@", alert[ALERT_INFO][KEY_POWER_TYPE]];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//set delegate to self
|
||||
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.2.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.2.2</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>LSUIElement</key>
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
7D564DEB1F1855E900B8AAD6 /* UpdateWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D564DE81F1855E900B8AAD6 /* UpdateWindow.xib */; };
|
||||
7D75537F1F22E40E0010FE88 /* PrefsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D75537D1F22E40E0010FE88 /* PrefsWindowController.m */; };
|
||||
7D7553801F22E40E0010FE88 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D75537E1F22E40E0010FE88 /* Preferences.xib */; };
|
||||
7D7553831F23199A0010FE88 /* prefsGeneral.png in Resources */ = {isa = PBXBuildFile; fileRef = 7D7553811F23199A0010FE88 /* prefsGeneral.png */; };
|
||||
7D7553841F23199A0010FE88 /* prefsUpdate.png in Resources */ = {isa = PBXBuildFile; fileRef = 7D7553821F23199A0010FE88 /* prefsUpdate.png */; };
|
||||
7DD2BF461F1C2B4200B33214 /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 7DD2BF431F1C2B4200B33214 /* logo.png */; };
|
||||
7DD2BF471F1C2B4200B33214 /* logoBG.png in Resources */ = {isa = PBXBuildFile; fileRef = 7DD2BF441F1C2B4200B33214 /* logoBG.png */; };
|
||||
@@ -45,6 +44,7 @@
|
||||
CD325425204DEAEA0059951B /* dndText@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CD325424204DEAEA0059951B /* dndText@2x.png */; };
|
||||
CD325427204E0C500059951B /* close.png in Resources */ = {isa = PBXBuildFile; fileRef = CD325426204E0C500059951B /* close.png */; };
|
||||
CD32542B204E0E420059951B /* closeAlt.png in Resources */ = {isa = PBXBuildFile; fileRef = CD32542A204E0E420059951B /* closeAlt.png */; };
|
||||
CD68AEE02110CD9E0019E431 /* prefsTriggers.png in Resources */ = {isa = PBXBuildFile; fileRef = CD68AEDF2110CD9D0019E431 /* prefsTriggers.png */; };
|
||||
CDAAC213201D0CD90032F2E6 /* three.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC212201D0CD80032F2E6 /* three.png */; };
|
||||
CDAAC215201D2DD30032F2E6 /* checkbox.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC214201D2DD30032F2E6 /* checkbox.png */; };
|
||||
CDAAC217201D54C30032F2E6 /* prefsLink.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC216201D54C20032F2E6 /* prefsLink.png */; };
|
||||
@@ -52,6 +52,8 @@
|
||||
CDAAC21C201D77390032F2E6 /* connected.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC21A201D77390032F2E6 /* connected.png */; };
|
||||
CDAAC21D201D77390032F2E6 /* unconnected.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC21B201D77390032F2E6 /* unconnected.png */; };
|
||||
CDAAC238201FD4660032F2E6 /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDAAC237201FD4660032F2E6 /* LocalAuthentication.framework */; };
|
||||
CDEADE52210214A0005054B0 /* usb.png in Resources */ = {isa = PBXBuildFile; fileRef = CDEADE502102149F005054B0 /* usb.png */; };
|
||||
CDEADE53210214A0005054B0 /* sleep.png in Resources */ = {isa = PBXBuildFile; fileRef = CDEADE51210214A0005054B0 /* sleep.png */; };
|
||||
CE0F559C1FD408BB00529259 /* dndText.png in Resources */ = {isa = PBXBuildFile; fileRef = CE0F559B1FD408BB00529259 /* dndText.png */; };
|
||||
CE133C5F1FD756CC00A29D67 /* dndIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CE133C5E1FD756CC00A29D67 /* dndIcon.png */; };
|
||||
CE85D3FE1FDB47B200E116A5 /* settings.png in Resources */ = {isa = PBXBuildFile; fileRef = CE85D3FD1FDB47B200E116A5 /* settings.png */; };
|
||||
@@ -109,7 +111,6 @@
|
||||
7D75537C1F22E40E0010FE88 /* PrefsWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefsWindowController.h; sourceTree = "<group>"; };
|
||||
7D75537D1F22E40E0010FE88 /* PrefsWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrefsWindowController.m; sourceTree = "<group>"; };
|
||||
7D75537E1F22E40E0010FE88 /* Preferences.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = Preferences.xib; sourceTree = "<group>"; };
|
||||
7D7553811F23199A0010FE88 /* prefsGeneral.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = prefsGeneral.png; sourceTree = "<group>"; };
|
||||
7D7553821F23199A0010FE88 /* prefsUpdate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = prefsUpdate.png; sourceTree = "<group>"; };
|
||||
7DD2BF431F1C2B4200B33214 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = "<group>"; };
|
||||
7DD2BF441F1C2B4200B33214 /* logoBG.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logoBG.png; sourceTree = "<group>"; };
|
||||
@@ -133,6 +134,7 @@
|
||||
CD325424204DEAEA0059951B /* dndText@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dndText@2x.png"; path = "../../../shared/images/dndText@2x.png"; sourceTree = "<group>"; };
|
||||
CD325426204E0C500059951B /* close.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = close.png; sourceTree = "<group>"; };
|
||||
CD32542A204E0E420059951B /* closeAlt.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = closeAlt.png; sourceTree = "<group>"; };
|
||||
CD68AEDF2110CD9D0019E431 /* prefsTriggers.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = prefsTriggers.png; sourceTree = "<group>"; };
|
||||
CDAAC212201D0CD80032F2E6 /* three.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = three.png; sourceTree = "<group>"; };
|
||||
CDAAC214201D2DD30032F2E6 /* checkbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = checkbox.png; sourceTree = "<group>"; };
|
||||
CDAAC216201D54C20032F2E6 /* prefsLink.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = prefsLink.png; sourceTree = "<group>"; };
|
||||
@@ -140,6 +142,8 @@
|
||||
CDAAC21A201D77390032F2E6 /* connected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = connected.png; sourceTree = "<group>"; };
|
||||
CDAAC21B201D77390032F2E6 /* unconnected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = unconnected.png; sourceTree = "<group>"; };
|
||||
CDAAC237201FD4660032F2E6 /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = System/Library/Frameworks/LocalAuthentication.framework; sourceTree = SDKROOT; };
|
||||
CDEADE502102149F005054B0 /* usb.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = usb.png; sourceTree = "<group>"; };
|
||||
CDEADE51210214A0005054B0 /* sleep.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = sleep.png; sourceTree = "<group>"; };
|
||||
CE0F559B1FD408BB00529259 /* dndText.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dndText.png; path = ../../../shared/images/dndText.png; sourceTree = "<group>"; };
|
||||
CE133C5E1FD756CC00A29D67 /* dndIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dndIcon.png; path = ../../../shared/images/dndIcon.png; sourceTree = "<group>"; };
|
||||
CE85D3FD1FDB47B200E116A5 /* settings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = settings.png; sourceTree = "<group>"; };
|
||||
@@ -242,6 +246,9 @@
|
||||
7D564DD31F18441500B8AAD6 /* Images */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD68AEDF2110CD9D0019E431 /* prefsTriggers.png */,
|
||||
CDEADE51210214A0005054B0 /* sleep.png */,
|
||||
CDEADE502102149F005054B0 /* usb.png */,
|
||||
CD32542A204E0E420059951B /* closeAlt.png */,
|
||||
CD325426204E0C500059951B /* close.png */,
|
||||
CD325424204DEAEA0059951B /* dndText@2x.png */,
|
||||
@@ -262,7 +269,6 @@
|
||||
CE133C5E1FD756CC00A29D67 /* dndIcon.png */,
|
||||
CE0F559B1FD408BB00529259 /* dndText.png */,
|
||||
CE968A9E1FCC66A300AD6B78 /* prefsAction.png */,
|
||||
7D7553811F23199A0010FE88 /* prefsGeneral.png */,
|
||||
7D7553821F23199A0010FE88 /* prefsUpdate.png */,
|
||||
7DD2BF431F1C2B4200B33214 /* logo.png */,
|
||||
7DD2BF441F1C2B4200B33214 /* logoBG.png */,
|
||||
@@ -330,7 +336,7 @@
|
||||
7D564DA11F18434F00B8AAD6 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 0930;
|
||||
ORGANIZATIONNAME = "Objective-See";
|
||||
TargetAttributes = {
|
||||
7D564DA81F18434F00B8AAD6 = {
|
||||
@@ -368,6 +374,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CD32542B204E0E420059951B /* closeAlt.png in Resources */,
|
||||
CDEADE53210214A0005054B0 /* sleep.png in Resources */,
|
||||
CD17D56E20178DFC00F798D7 /* mobilePhone.png in Resources */,
|
||||
CD1FD56B2089224F00151D1C /* appStore.pdf in Resources */,
|
||||
CD2F407F204B417E0066673E /* alert.png in Resources */,
|
||||
@@ -382,13 +389,14 @@
|
||||
CDAAC213201D0CD90032F2E6 /* three.png in Resources */,
|
||||
CDAAC219201D72780032F2E6 /* linked.png in Resources */,
|
||||
CD325425204DEAEA0059951B /* dndText@2x.png in Resources */,
|
||||
CDEADE52210214A0005054B0 /* usb.png in Resources */,
|
||||
7DD2BF481F1C2B4200B33214 /* logoOver.png in Resources */,
|
||||
7D7553801F22E40E0010FE88 /* Preferences.xib in Resources */,
|
||||
7D7553831F23199A0010FE88 /* prefsGeneral.png in Resources */,
|
||||
CD17D5772017941C00F798D7 /* laptop.png in Resources */,
|
||||
CD17D58520179BC700F798D7 /* two.png in Resources */,
|
||||
CD325427204E0C500059951B /* close.png in Resources */,
|
||||
7D564DD61F18441500B8AAD6 /* Assets.xcassets in Resources */,
|
||||
CD68AEE02110CD9E0019E431 /* prefsTriggers.png in Resources */,
|
||||
CD17D57020178EB500F798D7 /* one.png in Resources */,
|
||||
7D7553841F23199A0010FE88 /* prefsUpdate.png in Resources */,
|
||||
7D564DDC1F18441500B8AAD6 /* AboutWindow.xib in Resources */,
|
||||
@@ -418,7 +426,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "#for normal builds\n# ->just copy into app\nmkdir -p \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"\ncp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb Helper.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"";
|
||||
shellScript = "mkdir -p \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"\n\n#archiving\nif [[ $BUILT_PRODUCTS_DIR = *\"ArchiveIntermediates\"* ]]; then\n cp -R -f \"$PROJECT_TEMP_ROOT/UninstalledProducts/macosx/Do Not Disturb Helper.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"\n\n#normal build\nelse\n cp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb Helper.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"\nfi";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
@@ -477,6 +485,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@@ -484,6 +493,7 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@@ -530,6 +540,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
@@ -537,6 +548,7 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@@ -580,6 +592,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd";
|
||||
PRODUCT_NAME = "Do Not Disturb";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -601,6 +614,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd";
|
||||
PRODUCT_NAME = "Do Not Disturb";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
@@ -40,7 +40,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@@ -58,9 +57,8 @@
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
language = ""
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
@@ -77,6 +75,12 @@
|
||||
ReferencedContainer = "container:mainApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "-prefs"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 181 B After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
@@ -17,9 +17,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.2.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.2.2</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||
<capability name="box content view" minToolsVersion="7.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@@ -24,6 +24,7 @@
|
||||
<outlet property="qrcPanel" destination="vdL-RT-p6a" id="KrV-Fe-sK0"/>
|
||||
<outlet property="qrcProgressIndicator" destination="pUS-KZ-De6" id="EYG-28-zkH"/>
|
||||
<outlet property="toolbar" destination="V8g-Ya-LK4" id="SH2-6E-QST"/>
|
||||
<outlet property="triggersView" destination="BuY-2M-Ecx" id="hrr-N9-ajg"/>
|
||||
<outlet property="updateButton" destination="Mtn-pi-zIl" id="Oe1-Jy-nMH"/>
|
||||
<outlet property="updateIndicator" destination="o0T-ra-4H0" id="DwL-OB-WQR"/>
|
||||
<outlet property="updateLabel" destination="Oe2-Ye-1s6" id="1gP-K0-cpP"/>
|
||||
@@ -36,15 +37,15 @@
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="600" height="383"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" wantsLayer="YES" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="383"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="X2d-3b-ceM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="62"/>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TfC-c7-kXd">
|
||||
<rect key="frame" x="154" y="0.0" width="293" height="46"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" image="dndText" id="W8J-sT-YoM"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="dndText" id="EOL-U2-Wgh"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
</view>
|
||||
@@ -52,22 +53,27 @@
|
||||
<allowedToolbarItems>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="J66-tT-qAf"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="6nW-4K-zf4"/>
|
||||
<toolbarItem implicitItemIdentifier="99F00439-5E3B-4FBB-BC65-3E1F7EBDDBC6" explicitItemIdentifier="general" label="general" paletteLabel="general" image="prefsGeneral" selectable="YES" id="Twx-TJ-y2Q">
|
||||
<toolbarItem implicitItemIdentifier="99F00439-5E3B-4FBB-BC65-3E1F7EBDDBC6" explicitItemIdentifier="general" label="general" paletteLabel="general" image="dndIcon" selectable="YES" id="Twx-TJ-y2Q">
|
||||
<connections>
|
||||
<action selector="toolbarButtonHandler:" target="-2" id="9JH-zR-BcH"/>
|
||||
</connections>
|
||||
</toolbarItem>
|
||||
<toolbarItem implicitItemIdentifier="48B3FCFA-8A19-4D19-A840-E21E6D564389" explicitItemIdentifier="action" label="action" paletteLabel="action" tag="1" image="prefsAction" selectable="YES" id="hqU-b9-59A">
|
||||
<toolbarItem implicitItemIdentifier="0204F7A2-F780-423C-89FB-28784C971A9A" explicitItemIdentifier="triggers" label="triggers" paletteLabel="triggers" tag="1" image="prefsTriggers" selectable="YES" id="pr7-Pz-jdz">
|
||||
<connections>
|
||||
<action selector="toolbarButtonHandler:" target="-2" id="jYk-kP-mSc"/>
|
||||
</connections>
|
||||
</toolbarItem>
|
||||
<toolbarItem implicitItemIdentifier="48B3FCFA-8A19-4D19-A840-E21E6D564389" explicitItemIdentifier="action" label="action" paletteLabel="action" tag="2" image="prefsAction" selectable="YES" id="hqU-b9-59A">
|
||||
<connections>
|
||||
<action selector="toolbarButtonHandler:" target="-2" id="dy9-vy-N89"/>
|
||||
</connections>
|
||||
</toolbarItem>
|
||||
<toolbarItem implicitItemIdentifier="B0FD7AF2-DAC5-45EF-A31B-2E2C7CB85294" explicitItemIdentifier="update" label="update" paletteLabel="update" tag="3" image="prefsUpdate" selectable="YES" id="2Fi-c8-fnE">
|
||||
<toolbarItem implicitItemIdentifier="B0FD7AF2-DAC5-45EF-A31B-2E2C7CB85294" explicitItemIdentifier="update" label="update" paletteLabel="update" tag="4" image="prefsUpdate" selectable="YES" id="2Fi-c8-fnE">
|
||||
<connections>
|
||||
<action selector="toolbarButtonHandler:" target="-2" id="jeu-wN-mgR"/>
|
||||
</connections>
|
||||
</toolbarItem>
|
||||
<toolbarItem implicitItemIdentifier="5DB39F09-CC43-4EC3-BF61-362FDA2DF782" explicitItemIdentifier="link" label="link" paletteLabel="link" tag="2" image="prefsLink" selectable="YES" id="43J-tU-rUa">
|
||||
<toolbarItem implicitItemIdentifier="5DB39F09-CC43-4EC3-BF61-362FDA2DF782" explicitItemIdentifier="link" label="link" paletteLabel="link" tag="3" image="prefsLink" selectable="YES" id="43J-tU-rUa">
|
||||
<connections>
|
||||
<action selector="toolbarButtonHandler:" target="-2" id="tSK-K0-f7H"/>
|
||||
</connections>
|
||||
@@ -76,6 +82,8 @@
|
||||
<defaultToolbarItems>
|
||||
<toolbarItem reference="Twx-TJ-y2Q"/>
|
||||
<toolbarItem reference="J66-tT-qAf"/>
|
||||
<toolbarItem reference="pr7-Pz-jdz"/>
|
||||
<toolbarItem reference="J66-tT-qAf"/>
|
||||
<toolbarItem reference="hqU-b9-59A"/>
|
||||
<toolbarItem reference="J66-tT-qAf"/>
|
||||
<toolbarItem reference="43J-tU-rUa"/>
|
||||
@@ -153,7 +161,7 @@
|
||||
<button fixedFrame="YES" tag="3" translatesAutoresizingMaskIntoConstraints="NO" id="ANF-lj-j0H">
|
||||
<rect key="frame" x="37" y="156" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" enabled="NO" inset="2" id="Fpb-6d-DfT">
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="Fpb-6d-DfT">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="14" name="Consolas-Bold"/>
|
||||
</buttonCell>
|
||||
@@ -164,7 +172,7 @@
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="F9r-H0-4xe">
|
||||
<rect key="frame" x="72" y="157" width="471" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="'Touch ID' Mode" id="l1H-sS-Md8">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Authentication Mode" id="l1H-sS-Md8">
|
||||
<font key="font" size="13" name="Menlo-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -173,13 +181,13 @@
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" preferredMaxLayoutWidth="471" translatesAutoresizingMaskIntoConstraints="NO" id="BhQ-tq-9gJ">
|
||||
<rect key="frame" x="72" y="138" width="508" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Suppress alerts if proceeded by a Touch ID login (10.13.4+)." id="yKN-Kc-8Q2">
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Ignore events if computer unlocked via Touch ID or Apple Watch." id="yKN-Kc-8Q2">
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button fixedFrame="YES" tag="7" translatesAutoresizingMaskIntoConstraints="NO" id="OkJ-ds-qSY">
|
||||
<button fixedFrame="YES" tag="4" translatesAutoresizingMaskIntoConstraints="NO" id="OkJ-ds-qSY">
|
||||
<rect key="frame" x="37" y="99" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="HEY-GS-vSr">
|
||||
@@ -208,30 +216,95 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button fixedFrame="YES" tag="4" translatesAutoresizingMaskIntoConstraints="NO" id="5ep-7h-VpU">
|
||||
<rect key="frame" x="37" y="42" width="29" height="18"/>
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="852" y="437"/>
|
||||
</customView>
|
||||
<customView id="BuY-2M-Ecx" userLabel="Triggers">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="322"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<button fixedFrame="YES" tag="5" translatesAutoresizingMaskIntoConstraints="NO" id="QSk-EX-Gs3">
|
||||
<rect key="frame" x="37" y="270" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="J3b-LL-38M">
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" enabled="NO" inset="2" id="4Ia-YW-I03">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="14" name="Consolas-Bold"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="togglePreference:" target="-2" id="5gO-Zo-43d"/>
|
||||
<action selector="togglePreference:" target="-2" id="ko3-U3-K1d"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Yza-iC-hAP">
|
||||
<rect key="frame" x="72" y="42" width="160" height="19"/>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="c2q-TO-7Hx">
|
||||
<rect key="frame" x="72" y="271" width="160" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Start at Login" id="ksD-bk-5jE">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Laptop Lid Open" id="svL-i1-bx7">
|
||||
<font key="font" size="13" name="Menlo-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" preferredMaxLayoutWidth="471" translatesAutoresizingMaskIntoConstraints="NO" id="LOC-tP-KQd">
|
||||
<rect key="frame" x="72" y="22" width="475" height="19"/>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" preferredMaxLayoutWidth="471" translatesAutoresizingMaskIntoConstraints="NO" id="9cA-xI-Rkq">
|
||||
<rect key="frame" x="72" y="253" width="475" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Automatically start login item." id="k4V-lS-86b">
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Alert when your laptop lid is opened." id="eYK-5x-T41">
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button fixedFrame="YES" tag="6" translatesAutoresizingMaskIntoConstraints="NO" id="Tdc-FL-Prs">
|
||||
<rect key="frame" x="37" y="213" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="Lxz-uf-N9R">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="14" name="Consolas-Bold"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="togglePreference:" target="-2" id="C4T-Ye-XAC"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wzx-aD-Ob5">
|
||||
<rect key="frame" x="72" y="214" width="161" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="USB Device Insertion" id="a2r-f0-Qw2">
|
||||
<font key="font" size="13" name="Menlo-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" preferredMaxLayoutWidth="471" translatesAutoresizingMaskIntoConstraints="NO" id="xBV-DA-rOc">
|
||||
<rect key="frame" x="72" y="195" width="475" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Alert when a USB device is plugged in." id="yaL-Sz-w38">
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button fixedFrame="YES" tag="7" translatesAutoresizingMaskIntoConstraints="NO" id="G6G-cU-bdG">
|
||||
<rect key="frame" x="37" y="156" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="oKm-iS-CO8">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="14" name="Consolas-Bold"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="togglePreference:" target="-2" id="whf-Fn-MSZ"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CjK-AK-Uzg">
|
||||
<rect key="frame" x="72" y="157" width="471" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Power Events" id="YR8-oc-TgU">
|
||||
<font key="font" size="13" name="Menlo-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" preferredMaxLayoutWidth="471" translatesAutoresizingMaskIntoConstraints="NO" id="7Cw-J0-A9x">
|
||||
<rect key="frame" x="72" y="118" width="490" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Alert when the your computer is powered on, awakened, or when the screen saver is stopped. " id="yW3-Uo-Ir7">
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -244,7 +317,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="311"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<button fixedFrame="YES" tag="5" translatesAutoresizingMaskIntoConstraints="NO" id="1z0-vD-5Vz">
|
||||
<button fixedFrame="YES" tag="8" translatesAutoresizingMaskIntoConstraints="NO" id="1z0-vD-5Vz">
|
||||
<rect key="frame" x="37" y="259" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="0eO-nb-SYy">
|
||||
@@ -273,8 +346,8 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button fixedFrame="YES" tag="6" translatesAutoresizingMaskIntoConstraints="NO" id="Od2-P2-SXK">
|
||||
<rect key="frame" x="37" y="201" width="29" height="18"/>
|
||||
<button fixedFrame="YES" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="Od2-P2-SXK">
|
||||
<rect key="frame" x="37" y="202" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="qyn-YP-C2s">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
@@ -285,7 +358,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BXf-fg-RpF">
|
||||
<rect key="frame" x="72" y="201" width="59" height="19"/>
|
||||
<rect key="frame" x="72" y="203" width="59" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Monitor" id="YH2-4b-Iv5">
|
||||
<font key="font" size="13" name="Menlo-Bold"/>
|
||||
@@ -302,6 +375,26 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button fixedFrame="YES" tag="10" translatesAutoresizingMaskIntoConstraints="NO" id="C6E-J8-lhh">
|
||||
<rect key="frame" x="37" y="132" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="ngn-La-kHu">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="14" name="Consolas-Bold"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="togglePreference:" target="-2" id="d0h-1p-AtX"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Np1-aP-w1p">
|
||||
<rect key="frame" x="72" y="133" width="98" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Snap Picture" id="BQ4-1f-ZXw">
|
||||
<font key="font" size="13" name="Menlo-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eWd-63-7Gn">
|
||||
<rect key="frame" x="198" y="257" width="354" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
@@ -314,6 +407,15 @@
|
||||
<outlet property="delegate" destination="-2" id="DAs-b2-8Zb"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" preferredMaxLayoutWidth="471" translatesAutoresizingMaskIntoConstraints="NO" id="cuP-oI-A6A">
|
||||
<rect key="frame" x="72" y="113" width="475" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Automatically take a picture via the webcam." id="7Xg-3U-FQp">
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="911" y="901.5"/>
|
||||
</customView>
|
||||
@@ -366,7 +468,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<button fixedFrame="YES" tag="8" translatesAutoresizingMaskIntoConstraints="NO" id="dml-JS-liI">
|
||||
<button fixedFrame="YES" tag="11" translatesAutoresizingMaskIntoConstraints="NO" id="dml-JS-liI">
|
||||
<rect key="frame" x="37" y="220" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="ljs-bE-JTP">
|
||||
@@ -445,7 +547,7 @@
|
||||
<rect key="frame" x="322" y="115" width="258" height="153"/>
|
||||
<clipView key="contentView" id="FSf-NQ-BdZ">
|
||||
<rect key="frame" x="1" y="1" width="256" height="151"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView editable="NO" selectable="NO" importsGraphics="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" usesRuler="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="9cB-rx-0JH">
|
||||
<rect key="frame" x="0.0" y="0.0" width="256" height="151"/>
|
||||
@@ -523,7 +625,7 @@
|
||||
<windowStyleMask key="styleMask" utility="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="2832" y="172" width="594" height="440"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" id="jEo-ef-0kG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="594" height="440"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
@@ -604,6 +706,7 @@
|
||||
<image name="close" width="24" height="24"/>
|
||||
<image name="closeAlt" width="24" height="24"/>
|
||||
<image name="connected" width="128" height="128"/>
|
||||
<image name="dndIcon" width="256" height="256"/>
|
||||
<image name="dndText" width="164.57142639160156" height="21.188571929931641"/>
|
||||
<image name="imageCell:eTI-5p-4rR:image" width="256" height="256">
|
||||
<mutableData key="keyedArchiveRepresentation">
|
||||
@@ -5125,9 +5228,9 @@ IGsABCB5AAQgfQAEIIQABCCJAAQglgAEIJkABCCmAAQgqwAEILMABCC2AAQguwAEIMMABCDGAAQg2AAE
|
||||
INsABCDgAAAAAAAABAEAAAAAAAAAVgAAAAAAAAAAAAAAAAAEIOI
|
||||
</mutableData>
|
||||
</image>
|
||||
<image name="prefsAction" width="32" height="32"/>
|
||||
<image name="prefsGeneral" width="32" height="32"/>
|
||||
<image name="prefsLink" width="32" height="32"/>
|
||||
<image name="prefsUpdate" width="32" height="32"/>
|
||||
<image name="prefsAction" width="256" height="256"/>
|
||||
<image name="prefsLink" width="256" height="256"/>
|
||||
<image name="prefsTriggers" width="224" height="205"/>
|
||||
<image name="prefsUpdate" width="256" height="256"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -17,13 +17,16 @@
|
||||
#define TOOLBAR_GENERAL 0
|
||||
|
||||
//action view
|
||||
#define TOOLBAR_ACTION 1
|
||||
#define TOOLBAR_TRIGGERS 1
|
||||
|
||||
//action view
|
||||
#define TOOLBAR_ACTION 2
|
||||
|
||||
//link view
|
||||
#define TOOLBAR_LINK 2
|
||||
#define TOOLBAR_LINK 3
|
||||
|
||||
//update view
|
||||
#define TOOLBAR_UPDATE 3
|
||||
#define TOOLBAR_UPDATE 4
|
||||
|
||||
//tool bar id for 'general'
|
||||
#define TOOLBAR_GENERAL_ID @"general"
|
||||
@@ -34,23 +37,34 @@
|
||||
//no icon mode button
|
||||
#define BUTTON_NO_ICON_MODE 2
|
||||
|
||||
//touch id mode button
|
||||
#define BUTTON_TOUCHID_MODE 3
|
||||
//auth mode button
|
||||
#define BUTTON_AUTH_MODE 3
|
||||
|
||||
//remote tasking
|
||||
#define BUTTON_TASKING_MODE 4
|
||||
|
||||
|
||||
//lid open trigger
|
||||
#define BUTTON_LID_TRIGGER 5
|
||||
|
||||
//usb device trigger
|
||||
#define BUTTON_DEVICE_TRIGGER 6
|
||||
|
||||
//power events trigger
|
||||
#define BUTTON_POWER_TRIGGER 7
|
||||
|
||||
//start mode button
|
||||
#define BUTTON_START_MODE 4
|
||||
|
||||
//execute action button
|
||||
#define BUTTON_EXECUTE_ACTION 5
|
||||
#define BUTTON_EXECUTE_ACTION 8
|
||||
|
||||
//monitor button
|
||||
#define BUTTON_MONITOR_ACTION 6
|
||||
#define BUTTON_MONITOR_ACTION 9
|
||||
|
||||
//no remote tasking button
|
||||
#define BUTTON_NO_REMOTE_TASKING 7
|
||||
//snap picture button
|
||||
#define BUTTON_PHOTO_ACTION 10
|
||||
|
||||
//no updates button
|
||||
#define BUTTON_NO_UPDATES_MODE 8
|
||||
#define BUTTON_NO_UPDATES_MODE 11
|
||||
|
||||
@interface PrefsWindowController : NSWindowController <NSTextFieldDelegate, NSToolbarDelegate>
|
||||
|
||||
@@ -68,6 +82,9 @@
|
||||
//general prefs view
|
||||
@property (weak) IBOutlet NSView *generalView;
|
||||
|
||||
//triggers view
|
||||
@property (strong) IBOutlet NSView *triggersView;
|
||||
|
||||
//action view
|
||||
@property (weak) IBOutlet NSView *actionView;
|
||||
|
||||
|
||||
@@ -48,13 +48,12 @@
|
||||
//set general prefs as default
|
||||
[self toolbarButtonHandler:nil];
|
||||
|
||||
//enable touchID mode option
|
||||
// if: < 10.13.4 (check first!) && no touch bar
|
||||
if( (YES == [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10, 13, 4}]) &&
|
||||
(YES == hasTouchID()) )
|
||||
//clamshell?
|
||||
// enable laptop trigger option
|
||||
if(stateUnavailable != getLidState())
|
||||
{
|
||||
//enable button
|
||||
((NSButton*)[self.generalView viewWithTag:BUTTON_TOUCHID_MODE]).enabled = YES;
|
||||
((NSButton*)[self.triggersView viewWithTag:BUTTON_LID_TRIGGER]).enabled = YES;
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -63,7 +62,7 @@
|
||||
//required for toolbar item enable/disable
|
||||
-(BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem
|
||||
{
|
||||
return [toolbarItem isEnabled] ;
|
||||
return [toolbarItem isEnabled];
|
||||
}
|
||||
|
||||
//toolbar view handler
|
||||
@@ -109,11 +108,29 @@
|
||||
((NSButton*)[view viewWithTag:BUTTON_NO_ICON_MODE]).state = [self.preferences[PREF_NO_ICON_MODE] boolValue];
|
||||
|
||||
//set 'touch id' button state
|
||||
((NSButton*)[view viewWithTag:BUTTON_TOUCHID_MODE]).state = [self.preferences[PREF_TOUCHID_MODE] boolValue];
|
||||
((NSButton*)[view viewWithTag:BUTTON_AUTH_MODE]).state = [self.preferences[PREF_AUTH_MODE] boolValue];
|
||||
|
||||
//set 'no remote tasking' button state
|
||||
((NSButton*)[view viewWithTag:BUTTON_TASKING_MODE]).state = [self.preferences[PREF_NO_REMOTE_TASKING] boolValue];
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//triggers
|
||||
case TOOLBAR_TRIGGERS:
|
||||
{
|
||||
//set view
|
||||
view = self.triggersView;
|
||||
|
||||
//set 'lap lid' trigger button state
|
||||
((NSButton*)[view viewWithTag:BUTTON_LID_TRIGGER]).state = [self.preferences[PREF_LID_TRIGGER] boolValue];
|
||||
|
||||
//set 'usb device' trigger button state
|
||||
((NSButton*)[view viewWithTag:BUTTON_DEVICE_TRIGGER]).state = [self.preferences[PREF_DEVICE_TRIGGER] boolValue];
|
||||
|
||||
//set 'power events' trigger button state
|
||||
((NSButton*)[view viewWithTag:BUTTON_POWER_TRIGGER]).state = [self.preferences[PREF_POWER_TRIGGER] boolValue];
|
||||
|
||||
//set 'start mode' button state
|
||||
((NSButton*)[view viewWithTag:BUTTON_START_MODE]).state = [self.preferences[PREF_START_MODE] boolValue];
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -139,8 +156,8 @@
|
||||
//set 'monitor' button state
|
||||
((NSButton*)[view viewWithTag:BUTTON_MONITOR_ACTION]).state = [self.preferences[PREF_MONITOR_ACTION] boolValue];
|
||||
|
||||
//set 'no remote tasking' button state
|
||||
((NSButton*)[view viewWithTag:BUTTON_NO_REMOTE_TASKING]).state = [self.preferences[PREF_NO_REMOTE_TASKING] boolValue];
|
||||
//set 'photo action' button state
|
||||
((NSButton*)[view viewWithTag:BUTTON_PHOTO_ACTION]).state = [self.preferences[PREF_PHOTO_ACTION] boolValue];
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -304,6 +321,8 @@
|
||||
//set appropriate preference
|
||||
switch(((NSButton*)sender).tag)
|
||||
{
|
||||
/* GENERAL PREFS */
|
||||
|
||||
//passive mode
|
||||
case BUTTON_PASSIVE_MODE:
|
||||
{
|
||||
@@ -323,35 +342,54 @@
|
||||
break;
|
||||
}
|
||||
|
||||
//touch id mode
|
||||
case BUTTON_TOUCHID_MODE:
|
||||
//auth mode
|
||||
case BUTTON_AUTH_MODE:
|
||||
{
|
||||
//set pref
|
||||
preferences[PREF_TOUCHID_MODE] = state;
|
||||
preferences[PREF_AUTH_MODE] = state;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//start mode
|
||||
// also toggle here...
|
||||
case BUTTON_START_MODE:
|
||||
//remote tasking
|
||||
case BUTTON_TASKING_MODE:
|
||||
{
|
||||
//set pref
|
||||
preferences[PREF_START_MODE] = state;
|
||||
|
||||
//toggle login item in background
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^{
|
||||
//toggle
|
||||
if(YES != toggleLoginItem([NSURL fileURLWithPath:[((AppDelegate*)[[NSApplication sharedApplication] delegate]) path2LoginItem]], [preferences[PREF_START_MODE] intValue]))
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to toggle login item");
|
||||
}
|
||||
});
|
||||
preferences[PREF_NO_REMOTE_TASKING] = state;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* TRIGGER PREFS */
|
||||
|
||||
//lid trigger
|
||||
case BUTTON_LID_TRIGGER:
|
||||
{
|
||||
//set pref
|
||||
preferences[PREF_LID_TRIGGER] = state;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//usb device trigger
|
||||
case BUTTON_DEVICE_TRIGGER:
|
||||
{
|
||||
//set pref
|
||||
preferences[PREF_DEVICE_TRIGGER] = state;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//power trigger
|
||||
case BUTTON_POWER_TRIGGER:
|
||||
{
|
||||
//set pref
|
||||
preferences[PREF_POWER_TRIGGER] = state;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* ACTION PREFS */
|
||||
|
||||
//execute action
|
||||
// also toggle state of path
|
||||
@@ -375,14 +413,16 @@
|
||||
break;
|
||||
}
|
||||
|
||||
//no camera
|
||||
case BUTTON_NO_REMOTE_TASKING:
|
||||
//monitor mode
|
||||
case BUTTON_PHOTO_ACTION:
|
||||
{
|
||||
//set pref
|
||||
preferences[PREF_NO_REMOTE_TASKING] = state;
|
||||
preferences[PREF_PHOTO_ACTION] = state;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* UPDATE PREFS */
|
||||
|
||||
//(no) update mode
|
||||
case BUTTON_NO_UPDATES_MODE:
|
||||
@@ -395,7 +435,7 @@
|
||||
}
|
||||
|
||||
//tell daemon to update preferences
|
||||
[daemonComms updatePreferences:preferences];
|
||||
[self.daemonComms updatePreferences:preferences];
|
||||
|
||||
//restart login item if user toggle'd icon state
|
||||
// note: this has to be done after the prefs are written out by the daemon
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||
<capability name="box content view" minToolsVersion="7.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@@ -11,12 +11,16 @@
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="12Q-wb-usj" id="OBk-O9-kxj"/>
|
||||
<outlet property="activityMessage" destination="fFv-Gr-YPE" id="ItR-ES-c5V"/>
|
||||
<outlet property="appInfo" destination="Saf-Qg-NBo" id="xs0-qj-7dm"/>
|
||||
<outlet property="appInfo" destination="uXX-Wf-ZLL" id="x8l-zh-2Ww"/>
|
||||
<outlet property="deviceName" destination="cwA-Cr-acf" id="2Iv-JH-zGS"/>
|
||||
<outlet property="deviceTrigger" destination="1yX-PX-O3F" id="0PZ-dS-dxu"/>
|
||||
<outlet property="hostName" destination="mFe-eu-nNm" id="oRs-cQ-NN6"/>
|
||||
<outlet property="lidTrigger" destination="HhM-Wb-jX6" id="mqX-9A-Tlu"/>
|
||||
<outlet property="linkedView" destination="Bbb-NZ-tuF" id="vGv-tV-8Mb"/>
|
||||
<outlet property="powerTrigger" destination="gTR-JD-PmX" id="lLC-rw-fi7"/>
|
||||
<outlet property="qrcImageView" destination="mos-zb-KRK" id="kKD-Ww-Bkx"/>
|
||||
<outlet property="qrcView" destination="klO-RE-i9P" id="30O-Tc-jSC"/>
|
||||
<outlet property="triggerView" destination="Saf-Qg-NBo" id="Aaf-2f-ehE"/>
|
||||
<outlet property="welcomeView" destination="vZ0-Uk-9P1" id="JgS-86-4S1"/>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
@@ -27,7 +31,7 @@
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="800" height="500"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
<value key="minSize" type="size" width="800" height="500"/>
|
||||
<value key="maxSize" type="size" width="800" height="500"/>
|
||||
<view key="contentView" wantsLayer="YES" id="se5-gp-TjO">
|
||||
@@ -97,7 +101,7 @@
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" preferredMaxLayoutWidth="660" translatesAutoresizingMaskIntoConstraints="NO" id="cxG-zN-szL">
|
||||
<rect key="frame" x="31" y="180" width="738" height="117"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="center" title="'Do Not Disturb' attempts to detect 'evil maid' attacks,
alerting you if somebody tampers with your laptop!" id="tYf-YX-PsV">
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="center" title="'Do Not Disturb' attempts to detect 'evil maid' attacks,
alerting you if somebody tampers with your Mac!" id="tYf-YX-PsV">
|
||||
<font key="font" size="32" name="AvenirNextCondensed-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -106,33 +110,14 @@
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="-156" y="647"/>
|
||||
</customView>
|
||||
<customView id="Saf-Qg-NBo" userLabel="App Info">
|
||||
<customView id="Saf-Qg-NBo" userLabel="Triggers">
|
||||
<rect key="frame" x="0.0" y="0.0" width="800" height="500"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" preferredMaxLayoutWidth="660" translatesAutoresizingMaskIntoConstraints="NO" id="qwA-lo-6xT">
|
||||
<rect key="frame" x="68" y="426" width="664" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="center" title="Let's link with your iPhone to enable mobile alerts" id="SFE-Jt-OYq">
|
||||
<font key="font" size="32" name="AvenirNextCondensed-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hgC-yZ-fp2">
|
||||
<rect key="frame" x="342" y="292" width="116" height="73"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="unconnected" id="Mpj-kB-q4i"/>
|
||||
</imageView>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tSA-l2-uw1">
|
||||
<rect key="frame" x="458" y="267" width="142" height="124"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="mobilePhone" id="ijd-WJ-9VT"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" preferredMaxLayoutWidth="388" translatesAutoresizingMaskIntoConstraints="NO" id="OFG-Gz-3rE">
|
||||
<rect key="frame" x="18" y="157" width="764" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Download 'Do Not Disturb' from the iOS App Store" id="MAH-fc-gnv">
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="center" title="What should trigger 'Do Not Disturb'?" id="SFE-Jt-OYq">
|
||||
<font key="font" size="32" name="AvenirNextCondensed-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -145,18 +130,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="800" height="48"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="2" translatesAutoresizingMaskIntoConstraints="NO" id="XhZ-7d-es8">
|
||||
<rect key="frame" x="14" y="6" width="81" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Skip" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="jHq-Ss-1eG">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="buttonHandler:" target="-2" id="skW-Zf-sd1"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="3" translatesAutoresizingMaskIntoConstraints="NO" id="k0d-RO-RST">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="2" translatesAutoresizingMaskIntoConstraints="NO" id="k0d-RO-RST">
|
||||
<rect key="frame" x="715" y="6" width="81" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Next" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="7AI-8x-NIJ">
|
||||
@@ -172,19 +146,153 @@
|
||||
<color key="fillColor" red="0.57793885469999995" green="0.75859862570000003" blue="0.2368842065" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</box>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Stm-VG-w3v">
|
||||
<rect key="frame" x="206" y="267" width="138" height="124"/>
|
||||
<rect key="frame" x="76" y="150" width="180" height="200"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="laptop" id="tNr-00-iNk"/>
|
||||
</imageView>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9FN-FI-sj3">
|
||||
<rect key="frame" x="345" y="100" width="110" height="49"/>
|
||||
<button fixedFrame="YES" tag="5" translatesAutoresizingMaskIntoConstraints="NO" id="HhM-Wb-jX6">
|
||||
<rect key="frame" x="86" y="143" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="rounded" image="appStore" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="cPG-lr-39E">
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="6kw-r2-rmN">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="14" name="Consolas-Bold"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="e9r-Jq-TLi">
|
||||
<rect key="frame" x="111" y="143" width="140" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Laptop Lid Open" id="3rB-77-9nQ">
|
||||
<font key="font" size="15" name="Menlo-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button fixedFrame="YES" tag="5" translatesAutoresizingMaskIntoConstraints="NO" id="gTR-JD-PmX">
|
||||
<rect key="frame" x="581" y="143" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="ok3-Cj-tDO">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="14" name="Consolas-Bold"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gYG-uo-2F5">
|
||||
<rect key="frame" x="315" y="165" width="170" height="170"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="usb" id="fcP-xx-A5f"/>
|
||||
</imageView>
|
||||
<button fixedFrame="YES" tag="5" translatesAutoresizingMaskIntoConstraints="NO" id="1yX-PX-O3F">
|
||||
<rect key="frame" x="341" y="143" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="bJj-FO-Xp6">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="14" name="Consolas-Bold"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="93F-5x-Nuf">
|
||||
<rect key="frame" x="605" y="82" width="177" height="84"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Power On
Computer Wake
Screen Saver Off" id="uOY-7O-Nsb">
|
||||
<font key="font" size="15" name="Menlo-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fTz-Wm-yY8">
|
||||
<rect key="frame" x="571" y="170" width="159" height="159"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="sleep" id="LyW-2I-nNG"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Vd-M8-05L">
|
||||
<rect key="frame" x="365" y="143" width="122" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="USB Insertion" id="dHu-5b-Vk2">
|
||||
<font key="font" size="15" name="Menlo-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="831" y="-530"/>
|
||||
</customView>
|
||||
<customView id="uXX-Wf-ZLL" userLabel="App Info">
|
||||
<rect key="frame" x="0.0" y="0.0" width="800" height="500"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" preferredMaxLayoutWidth="660" translatesAutoresizingMaskIntoConstraints="NO" id="pzP-vr-mwp">
|
||||
<rect key="frame" x="68" y="426" width="664" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="center" title="Let's link with your iPhone to enable mobile alerts" id="b7f-6P-fss">
|
||||
<font key="font" size="32" name="AvenirNextCondensed-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3Ko-5I-ZkQ">
|
||||
<rect key="frame" x="342" y="292" width="116" height="73"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="unconnected" id="biq-NY-wHH"/>
|
||||
</imageView>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Rla-hF-y7t">
|
||||
<rect key="frame" x="458" y="267" width="142" height="124"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="mobilePhone" id="ks4-qM-EJX"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" preferredMaxLayoutWidth="388" translatesAutoresizingMaskIntoConstraints="NO" id="1NC-nB-9TF">
|
||||
<rect key="frame" x="18" y="157" width="764" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Download 'Do Not Disturb' from the iOS App Store" id="xMO-kA-ubY">
|
||||
<font key="font" size="32" name="AvenirNextCondensed-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box fixedFrame="YES" boxType="custom" borderType="none" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="2wk-PX-com">
|
||||
<rect key="frame" x="0.0" y="0.0" width="800" height="48"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<view key="contentView" ambiguous="YES" id="Cvt-0u-Fn9">
|
||||
<rect key="frame" x="0.0" y="0.0" width="800" height="48"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="3" translatesAutoresizingMaskIntoConstraints="NO" id="SzW-hq-Cay">
|
||||
<rect key="frame" x="14" y="6" width="81" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Skip" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="F4D-7D-b7M">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="buttonHandler:" target="-2" id="Q9F-RZ-B16"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="4" translatesAutoresizingMaskIntoConstraints="NO" id="IYF-UZ-e79">
|
||||
<rect key="frame" x="715" y="6" width="81" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Next" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="KzN-1a-Bgl">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="buttonHandler:" target="-2" id="4kt-qR-EdK"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<color key="fillColor" red="0.57793885469999995" green="0.75859862570000003" blue="0.2368842065" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</box>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pne-xe-SXP">
|
||||
<rect key="frame" x="206" y="267" width="138" height="124"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="laptop" id="Yka-Wc-tqb"/>
|
||||
</imageView>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SIf-al-GRB">
|
||||
<rect key="frame" x="337" y="94" width="127" height="55"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="rounded" image="appStore" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="rpd-Oh-aLh">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="downloadApp:" target="-2" id="IrW-7u-1OG"/>
|
||||
<action selector="downloadApp:" target="-2" id="u1k-Ns-xde"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
@@ -295,7 +403,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="800" height="48"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="4" translatesAutoresizingMaskIntoConstraints="NO" id="SCr-nL-4pA">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="5" translatesAutoresizingMaskIntoConstraints="NO" id="SCr-nL-4pA">
|
||||
<rect key="frame" x="705" y="6" width="81" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Done" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Jhe-Eu-d4x">
|
||||
@@ -4853,6 +4961,8 @@ INsABCDgAAAAAAAABAEAAAAAAAAAVgAAAAAAAAAAAAAAAAAEIOI
|
||||
<image name="laptop" width="256" height="256"/>
|
||||
<image name="linked" width="256" height="467"/>
|
||||
<image name="mobilePhone" width="512" height="512"/>
|
||||
<image name="sleep" width="256" height="256"/>
|
||||
<image name="unconnected" width="128" height="128"/>
|
||||
<image name="usb" width="256" height="256"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -17,12 +17,27 @@
|
||||
//welcome view
|
||||
@property (strong) IBOutlet NSView *welcomeView;
|
||||
|
||||
//app info view
|
||||
@property (strong) IBOutlet NSView *triggerView;
|
||||
|
||||
//app info view
|
||||
@property (strong) IBOutlet NSView *appInfo;
|
||||
|
||||
//config view
|
||||
@property (strong) IBOutlet NSView *qrcView;
|
||||
|
||||
//button
|
||||
// trigger for lid opens
|
||||
@property (weak) IBOutlet NSButton *lidTrigger;
|
||||
|
||||
//button
|
||||
// trigger for device insertions
|
||||
@property (weak) IBOutlet NSButton *deviceTrigger;
|
||||
|
||||
//button
|
||||
// trigger for power events
|
||||
@property (weak) IBOutlet NSButton *powerTrigger;
|
||||
|
||||
//activity indicator
|
||||
@property (weak) IBOutlet NSProgressIndicator *activityIndicator;
|
||||
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
#import "WelcomeWindowController.h"
|
||||
|
||||
#define VIEW_WELCOME 0
|
||||
#define VIEW_APP_INFO 1
|
||||
#define SKIP_LINKING 2
|
||||
#define VIEW_QRC 3
|
||||
#define VIEW_LINKED 4
|
||||
#define SELECT_TRIGGERS 1
|
||||
#define VIEW_APP_INFO 2
|
||||
#define SKIP_LINKING 3
|
||||
#define VIEW_QRC 4
|
||||
#define VIEW_LINKED 5
|
||||
|
||||
@implementation WelcomeWindowController
|
||||
|
||||
@@ -75,16 +76,48 @@
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (100 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
|
||||
|
||||
//set first responder
|
||||
[self.window makeFirstResponder:[self.welcomeView viewWithTag:VIEW_APP_INFO]];
|
||||
[self.window makeFirstResponder:[self.welcomeView viewWithTag:SELECT_TRIGGERS]];
|
||||
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//select triggers info
|
||||
case SELECT_TRIGGERS:
|
||||
{
|
||||
//remove prev. subview
|
||||
[[[self.window.contentView subviews] lastObject] removeFromSuperview];
|
||||
|
||||
//no a laptop?
|
||||
// uncheck and disable laptop lid trigger
|
||||
if(stateUnavailable == getLidState())
|
||||
{
|
||||
//uncheck
|
||||
self.lidTrigger.state = NSOffState;
|
||||
|
||||
//disable
|
||||
self.lidTrigger.enabled = NO;
|
||||
}
|
||||
|
||||
//set view
|
||||
[self.window.contentView addSubview:self.triggerView];
|
||||
|
||||
//make 'next' button first responder
|
||||
[self.window makeFirstResponder:[self.triggerView viewWithTag:VIEW_APP_INFO]];
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//app info
|
||||
case VIEW_APP_INFO:
|
||||
{
|
||||
//save trigger prefs
|
||||
[self setTriggers];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"saved triggers");
|
||||
|
||||
//remove prev. subview
|
||||
[[[self.window.contentView subviews] lastObject] removeFromSuperview];
|
||||
|
||||
@@ -130,6 +163,29 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//get user's prefs for triggers
|
||||
// then send them to daemon to save into prefs
|
||||
-(void)setTriggers
|
||||
{
|
||||
//daemon comms
|
||||
DaemonComms* daemonComms = nil;
|
||||
|
||||
//alloc/init
|
||||
daemonComms = [[DaemonComms alloc] init];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"setting trigger prefs");
|
||||
|
||||
//send to daemon
|
||||
// will update preferences
|
||||
[daemonComms updatePreferences:@{PREF_LID_TRIGGER:[NSNumber numberWithInteger:self.lidTrigger.state],
|
||||
PREF_DEVICE_TRIGGER:[NSNumber numberWithInteger:self.deviceTrigger.state],
|
||||
PREF_POWER_TRIGGER:[NSNumber numberWithInteger:self.powerTrigger.state]}];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#import "Logging.h"
|
||||
#import "Utilities.h"
|
||||
|
||||
#import <ServiceManagement/ServiceManagement.h>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
|
||||
@@ -1 +1 @@
|
||||
Lance Gaines, Ash Morgan, Jeff Golden, Nando Mendonca, Khalil Sehnaoui, Gamer_Bot
|
||||
Halo Privacy, Ash Morgan, Geoffrey Weber, Jeff Golden, Khalil Sehnaoui, Nando Mendonca, Gamer_Bot
|
||||
|
||||
@@ -43,28 +43,19 @@
|
||||
//iOS companion app URL
|
||||
#define IOS_APP_URL @"https://itunes.apple.com/us/app/do-not-disturb-companion/id1345055731?mt=8"
|
||||
|
||||
//action to install
|
||||
// also button title
|
||||
#define ACTION_INSTALL @"Install"
|
||||
//button title: upgrade
|
||||
#define ACTION_UPGRADE @"Upgrade"
|
||||
|
||||
//action to uninstall
|
||||
// also button title
|
||||
#define ACTION_UNINSTALL @"Uninstall"
|
||||
|
||||
//button title
|
||||
// close
|
||||
//button title: close
|
||||
#define ACTION_CLOSE @"Close"
|
||||
|
||||
//button title
|
||||
// next
|
||||
//button title: next
|
||||
#define ACTION_NEXT @"Next »"
|
||||
|
||||
//button title
|
||||
// no
|
||||
//button title: no
|
||||
#define ACTION_NO @"No"
|
||||
|
||||
//button title
|
||||
// yes
|
||||
//button title: yes
|
||||
#define ACTION_YES @"Yes!"
|
||||
|
||||
//frame shift
|
||||
@@ -144,12 +135,6 @@
|
||||
//product version url
|
||||
#define PRODUCT_VERSIONS_URL @"https://objective-see.com/products.json"
|
||||
|
||||
//flag to uninstall
|
||||
#define ACTION_UNINSTALL_FLAG 0
|
||||
|
||||
//flag to install
|
||||
#define ACTION_INSTALL_FLAG 1
|
||||
|
||||
//login item name
|
||||
#define LOGIN_ITEM_NAME @"Do Not Disturb Helper"
|
||||
|
||||
@@ -163,6 +148,18 @@
|
||||
// status
|
||||
#define PREF_IS_DISABLED @"disabled"
|
||||
|
||||
//prefs
|
||||
// lid trigger
|
||||
#define PREF_LID_TRIGGER @"lidTrigger"
|
||||
|
||||
//prefs
|
||||
// device trigger
|
||||
#define PREF_DEVICE_TRIGGER @"deviceTrigger"
|
||||
|
||||
//prefs
|
||||
// power trigger
|
||||
#define PREF_POWER_TRIGGER @"powerTrigger"
|
||||
|
||||
//prefs
|
||||
// passive mode
|
||||
#define PREF_PASSIVE_MODE @"passiveMode"
|
||||
@@ -172,8 +169,8 @@
|
||||
#define PREF_NO_ICON_MODE @"noIconMode"
|
||||
|
||||
//prefs
|
||||
// touchID mode
|
||||
#define PREF_TOUCHID_MODE @"touchIDMode"
|
||||
// auth mode
|
||||
#define PREF_AUTH_MODE @"touchIDMode"
|
||||
|
||||
//prefs
|
||||
// start mode
|
||||
@@ -195,6 +192,10 @@
|
||||
// monitor stuff
|
||||
#define PREF_MONITOR_ACTION @"monitorAction"
|
||||
|
||||
//pref
|
||||
// auto take photo
|
||||
#define PREF_PHOTO_ACTION @"photoAction"
|
||||
|
||||
//pref
|
||||
// no remote tasking
|
||||
#define PREF_NO_REMOTE_TASKING @"noRemoteTasking"
|
||||
@@ -203,6 +204,19 @@
|
||||
// update mode
|
||||
#define PREF_NO_UPDATES_MODE @"noUpdatesMode"
|
||||
|
||||
//trigger: all
|
||||
// based on prefs
|
||||
#define ALL_TRIGGERS 0x0
|
||||
|
||||
//trigger: lid
|
||||
#define LID_TRIGGER 0x1
|
||||
|
||||
//trigger: devices
|
||||
#define DEVICE_TRIGGER 0x2
|
||||
|
||||
//trigger: power
|
||||
#define POWER_TRIGGER 0x3
|
||||
|
||||
//log file
|
||||
#define LOG_FILE_NAME @"DND.log"
|
||||
|
||||
@@ -210,9 +224,20 @@
|
||||
// timestamp
|
||||
#define ALERT_TIMESTAMP @"timestamp"
|
||||
|
||||
//alert key
|
||||
// type (lid, usb, power)
|
||||
#define ALERT_TYPE @"eventType"
|
||||
|
||||
//alert key
|
||||
// info (specific to event type)
|
||||
#define ALERT_INFO @"info"
|
||||
|
||||
//key for device name
|
||||
#define KEY_DEVICE_NAME @"deviceName"
|
||||
|
||||
//key for power type
|
||||
#define KEY_POWER_TYPE @"powerType"
|
||||
|
||||
//key for host name
|
||||
#define KEY_HOST_NAME @"hostName"
|
||||
|
||||
@@ -294,5 +319,8 @@
|
||||
//monitoring timeout
|
||||
#define MONITORING_TIMEOUT 60*3
|
||||
|
||||
//unknown user
|
||||
#define USER_UNKNOWN @"unknown"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||