white-listing granularity is now down to the device level (mic/camera)
ui: stuff is resizable / fixed warnings
This commit is contained in:
parent
5ba5b585ba
commit
5a1f704931
|
@ -56,9 +56,9 @@
|
|||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"loading whitelist %@", path]);
|
||||
#endif
|
||||
|
||||
|
||||
//since file is created by priv'd XPC, it shouldn't be writeable
|
||||
// ...unless somebody maliciously creates it, so we check if that here
|
||||
// ...unless somebody maliciously creates it, so we check that here
|
||||
if(YES == [[NSFileManager defaultManager] isWritableFileAtPath:path])
|
||||
{
|
||||
//err msg
|
||||
|
@ -67,7 +67,7 @@
|
|||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
||||
//load
|
||||
self.whiteList = [NSMutableArray arrayWithContentsOfFile:path];
|
||||
|
||||
|
@ -834,7 +834,7 @@ bail:
|
|||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"audio procs from XPC: %@", audioProcesses]);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//generate notification for each process
|
||||
for(NSNumber* processID in audioProcesses)
|
||||
|
@ -1018,16 +1018,25 @@ bail:
|
|||
|
||||
//ignore whitelisted processes
|
||||
// ->for activation events, can check process path
|
||||
if( (YES == [DEVICE_ACTIVE isEqual:event[EVENT_DEVICE_STATUS]]) &&
|
||||
(YES == [self.whiteList containsObject:processPath]) )
|
||||
if(YES == [DEVICE_ACTIVE isEqual:event[EVENT_DEVICE_STATUS]])
|
||||
{
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"activation alert for process %@ is whitelisted, so ignoring", processPath]);
|
||||
#endif
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
//check each
|
||||
// ->need match on path and device (camera || mic)
|
||||
for(NSDictionary* item in self.whiteList)
|
||||
{
|
||||
//check path & device
|
||||
if( (YES == [item[EVENT_PROCESS_PATH] isEqualToString:processPath]) &&
|
||||
([item[EVENT_DEVICE] intValue] == deviceType.intValue) )
|
||||
{
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"activation alert for process %@ is whitelisted, so ignoring", item]);
|
||||
#endif
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
}
|
||||
//ignore whitelisted processes
|
||||
// ->for deactivation, ignore when no activation alert was shown (cuz process will have likely died, so no pid/path, etc)
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
// ->used for whitelisting
|
||||
@property (nonatomic, retain)NSString* processPath;
|
||||
|
||||
//device
|
||||
// ->used for whitelisting
|
||||
@property (nonatomic, retain)NSNumber* device;
|
||||
|
||||
//instance of av monitor
|
||||
@property (nonatomic, retain)AVMonitor* avMonitor;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
@implementation RememberWindowController
|
||||
|
||||
@synthesize device;
|
||||
@synthesize avMonitor;
|
||||
@synthesize processPath;
|
||||
|
||||
|
@ -45,18 +46,6 @@
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
//automatically invoked when window is closing
|
||||
// ->make ourselves unmodal
|
||||
-(void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
//make un-modal
|
||||
[[NSApplication sharedApplication] stopModal];
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
//save stuff into iVars
|
||||
// ->configure window w/ dynamic text
|
||||
-(void)configure:(NSUserNotification*)notification avMonitor:(AVMonitor*)monitor;
|
||||
|
@ -83,14 +72,18 @@
|
|||
// ->saved into iVar for whitelisting
|
||||
self.processPath = notification.userInfo[EVENT_PROCESS_PATH];
|
||||
|
||||
//grab device
|
||||
// ->saved into iVar for whitelisting
|
||||
self.device = notification.userInfo[EVENT_DEVICE];
|
||||
|
||||
//set device type for audio
|
||||
if(SOURCE_AUDIO.intValue == [notification.userInfo[EVENT_DEVICE] intValue])
|
||||
if(SOURCE_AUDIO.intValue == [self.device intValue])
|
||||
{
|
||||
//set
|
||||
deviceType = @"mic";
|
||||
}
|
||||
//set device type for mic
|
||||
else if(SOURCE_VIDEO.intValue == [notification.userInfo[EVENT_DEVICE] intValue])
|
||||
else if(SOURCE_VIDEO.intValue == [self.device intValue])
|
||||
{
|
||||
//set
|
||||
deviceType = @"camera";
|
||||
|
@ -131,7 +124,7 @@
|
|||
#endif
|
||||
|
||||
//invoke XPC method 'whitelistProcess' to add process to white list
|
||||
[[xpcConnection remoteObjectProxy] whitelistProcess:self.processPath reply:^(BOOL wasWhitelisted)
|
||||
[[xpcConnection remoteObjectProxy] whitelistProcess:self.processPath device:self.device reply:^(BOOL wasWhitelisted)
|
||||
{
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16E195" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
@ -14,47 +14,45 @@
|
|||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES" unifiedTitleAndToolbar="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES" texturedBackground="YES" unifiedTitleAndToolbar="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="422" height="123"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1058"/>
|
||||
<value key="minSize" type="size" width="422" height="123"/>
|
||||
<value key="maxSize" type="size" width="800" height="123"/>
|
||||
<view key="contentView" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="422" height="123"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
|
||||
<rect key="frame" x="10" y="36" width="104" height="82"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="82" id="hbh-Sm-Zhs"/>
|
||||
<constraint firstAttribute="width" constant="104" id="wAG-N8-wcA"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="icon" id="xKf-GK-m0k"/>
|
||||
</imageView>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Eaf-yA-bbe">
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Eaf-yA-bbe">
|
||||
<rect key="frame" x="20" y="6" width="94" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="94" id="PdH-hs-jAq"/>
|
||||
<constraint firstAttribute="height" constant="22" id="hIM-Jw-VTR"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="overSight" id="Ws8-bD-j2R"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OSm-xS-Dmd">
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OSm-xS-Dmd">
|
||||
<rect key="frame" x="120" y="47" width="290" height="56"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="56" id="W2y-ds-fJG"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" truncatesLastVisibleLine="YES" sendsActionOnEndEditing="YES" id="bBK-v0-ypq">
|
||||
<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 verticalHuggingPriority="750" fixedFrame="YES" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="RKg-ba-EQ4">
|
||||
<rect key="frame" x="177" y="11" width="127" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="yes, always" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0OU-M1-ErX">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="buttonHandler:" target="-2" id="LNd-1i-TBg"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
|
||||
<rect key="frame" x="310" y="11" width="98" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="just once" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
|
||||
<button verticalHuggingPriority="750" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
|
||||
<rect key="frame" x="303" y="11" width="111" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Just Once" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
|
@ -62,7 +60,30 @@
|
|||
<action selector="buttonHandler:" target="-2" id="yBL-R5-DDG"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="RKg-ba-EQ4">
|
||||
<rect key="frame" x="161" y="11" width="127" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Yes, Always" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0OU-M1-ErX">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="buttonHandler:" target="-2" id="LNd-1i-TBg"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="HZZ-Es-mpy" secondAttribute="bottom" constant="18" id="Dl1-Xj-w6N"/>
|
||||
<constraint firstAttribute="bottom" secondItem="OSm-xS-Dmd" secondAttribute="bottom" constant="47" id="Igd-JW-wvo"/>
|
||||
<constraint firstAttribute="bottom" secondItem="RKg-ba-EQ4" secondAttribute="bottom" constant="18" id="KUJ-j6-Bjl"/>
|
||||
<constraint firstAttribute="trailing" secondItem="RKg-ba-EQ4" secondAttribute="trailing" constant="140" id="Klc-7g-EQu"/>
|
||||
<constraint firstAttribute="trailing" secondItem="OSm-xS-Dmd" secondAttribute="trailing" constant="14" id="QcB-Yv-9vm"/>
|
||||
<constraint firstItem="OSm-xS-Dmd" firstAttribute="leading" secondItem="lEv-Wj-6S5" secondAttribute="trailing" constant="8" id="So9-MA-q9b"/>
|
||||
<constraint firstItem="lEv-Wj-6S5" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="10" id="WhZ-G2-Urs"/>
|
||||
<constraint firstItem="Eaf-yA-bbe" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" id="iJQ-GM-l7f"/>
|
||||
<constraint firstItem="lEv-Wj-6S5" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="5" id="pnZ-ff-hBv"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Eaf-yA-bbe" secondAttribute="bottom" constant="6" id="tae-Ir-cHI"/>
|
||||
<constraint firstAttribute="trailing" secondItem="HZZ-Es-mpy" secondAttribute="trailing" constant="14" id="yfU-kv-QZb"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
/* FUNCTION DEFINITIONS */
|
||||
|
||||
//send XPC message to remove process from whitelist file
|
||||
void unWhiteList(NSString* process);
|
||||
void unWhiteList(NSString* process, NSNumber* deviceType);
|
||||
|
||||
#endif /* main_h */
|
||||
|
|
|
@ -86,21 +86,21 @@ int main(int argc, const char * argv[])
|
|||
//bail
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
||||
//unwhitelist path/device
|
||||
else if(3 == argc)
|
||||
{
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, @"running 'un-whitelist me' logic");
|
||||
#endif
|
||||
|
||||
//remove from whitelist file
|
||||
unWhiteList([NSString stringWithUTF8String:argv[1]], [NSNumber numberWithInt:atoi(argv[2])]);
|
||||
|
||||
//assume its a path to a process to remove from whitelist
|
||||
else
|
||||
{
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, @"running 'un-whitelist me' logic");
|
||||
#endif
|
||||
|
||||
//remove from whitelist file
|
||||
unWhiteList([NSString stringWithUTF8String:argv[1]]);
|
||||
|
||||
//don't bail
|
||||
// ->let it start (as it was killed)
|
||||
}
|
||||
//don't bail
|
||||
// ->let it start (as it was killed)
|
||||
}
|
||||
|
||||
//launch app normally
|
||||
|
@ -113,7 +113,7 @@ bail:
|
|||
}
|
||||
|
||||
//send XPC message to remove process from whitelist file
|
||||
void unWhiteList(NSString* process)
|
||||
void unWhiteList(NSString* process, NSNumber* device)
|
||||
{
|
||||
//xpc connection
|
||||
__block NSXPCConnection* xpcConnection = nil;
|
||||
|
@ -129,11 +129,11 @@ void unWhiteList(NSString* process)
|
|||
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"sending XPC message to remove %@ from whitelist file", process]);
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"sending XPC message to remove %@/%@ from whitelist file", process, device]);
|
||||
#endif
|
||||
|
||||
//invoke XPC method 'whitelistProcess' to add process to white list
|
||||
[[xpcConnection remoteObjectProxy] unWhitelistProcess:process reply:^(BOOL wasRemoved)
|
||||
[[xpcConnection remoteObjectProxy] unWhitelistProcess:process device:device reply:^(BOOL wasRemoved)
|
||||
{
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -455,6 +455,11 @@ bail:
|
|||
configuration = @{NSWorkspaceLaunchConfigurationArguments:args};
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"starting login item with: %@/%@", configuration, args]);
|
||||
#endif
|
||||
|
||||
//launch it
|
||||
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL fileURLWithPath:loginItem] options:NSWorkspaceLaunchWithoutActivation configuration:configuration error:&error];
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16E195" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
@ -14,11 +14,12 @@
|
|||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="White Listed Applications" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="611" height="270"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1058"/>
|
||||
<value key="minSize" type="size" width="500" height="100"/>
|
||||
<value key="maxSize" type="size" width="1500" height="500"/>
|
||||
<view key="contentView" wantsLayer="YES" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="611" height="270"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
|
@ -36,7 +37,7 @@
|
|||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="608" minWidth="40" maxWidth="1000" id="ocl-vV-SZu">
|
||||
<tableColumn width="608" minWidth="40" maxWidth="1500" id="ocl-vV-SZu">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -55,10 +56,14 @@
|
|||
<subviews>
|
||||
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="JiF-Nx-dl5">
|
||||
<rect key="frame" x="3" y="7" width="40" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="Ek4-aX-zze"/>
|
||||
<constraint firstAttribute="width" constant="40" id="LIx-0S-38a"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSColorPanel" id="v3A-16-OyI"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="JMN-i9-vxR">
|
||||
<rect key="frame" x="54" y="21" width="523" height="26"/>
|
||||
<rect key="frame" x="54" y="21" width="525" height="26"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Item Category" id="2GD-5k-sEf">
|
||||
<font key="font" size="17" name="Menlo-Bold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -66,10 +71,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="w9P-yZ-pho">
|
||||
<rect key="frame" x="54" y="8" width="523" height="17"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="519" id="kmq-rD-zZS"/>
|
||||
</constraints>
|
||||
<rect key="frame" x="54" y="8" width="525" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Item Category Description" id="EZN-NC-GXx">
|
||||
<font key="font" size="11" name="Menlo-Regular"/>
|
||||
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
|
@ -77,7 +79,11 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aWW-9r-3lC">
|
||||
<rect key="frame" x="583" y="19" width="14" height="15"/>
|
||||
<rect key="frame" x="585" y="19" width="20" height="15"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="20" id="6gy-ZI-MZN"/>
|
||||
<constraint firstAttribute="height" constant="15" id="iy3-ST-MU7"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="NSStopProgressFreestandingTemplate" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="wdw-rZ-IR3">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -88,19 +94,20 @@
|
|||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="JiF-Nx-dl5" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="7" id="0og-eM-P5A"/>
|
||||
<constraint firstItem="aWW-9r-3lC" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="20" id="2Hq-gF-RRx"/>
|
||||
<constraint firstAttribute="bottom" secondItem="JMN-i9-vxR" secondAttribute="bottom" constant="21" id="2lm-V9-MgG"/>
|
||||
<constraint firstItem="w9P-yZ-pho" firstAttribute="trailing" secondItem="JMN-i9-vxR" secondAttribute="trailing" id="3zL-0B-Yt0"/>
|
||||
<constraint firstItem="JMN-i9-vxR" firstAttribute="top" secondItem="JiF-Nx-dl5" secondAttribute="top" id="4ZQ-hO-YeB"/>
|
||||
<constraint firstAttribute="bottom" secondItem="aWW-9r-3lC" secondAttribute="bottom" constant="19" id="JXs-JW-Xg3"/>
|
||||
<constraint firstItem="w9P-yZ-pho" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="29" id="Rbh-tU-0B0"/>
|
||||
<constraint firstItem="JiF-Nx-dl5" firstAttribute="leading" secondItem="moN-VP-hzI" secondAttribute="leading" constant="3" id="UxO-Jr-Zzk"/>
|
||||
<constraint firstItem="w9P-yZ-pho" firstAttribute="leading" secondItem="JMN-i9-vxR" secondAttribute="leading" id="d1t-pb-hcW"/>
|
||||
<constraint firstItem="w9P-yZ-pho" firstAttribute="leading" secondItem="JiF-Nx-dl5" secondAttribute="trailing" constant="13" id="dD6-u5-DZw"/>
|
||||
<constraint firstItem="w9P-yZ-pho" firstAttribute="leading" secondItem="moN-VP-hzI" secondAttribute="leading" constant="56" id="mQY-GF-Ndc"/>
|
||||
<constraint firstAttribute="trailing" secondItem="aWW-9r-3lC" secondAttribute="trailing" constant="11" id="n4e-65-kcp"/>
|
||||
<constraint firstAttribute="bottom" secondItem="JiF-Nx-dl5" secondAttribute="bottom" constant="7" id="na5-b4-JAs"/>
|
||||
<constraint firstAttribute="bottom" secondItem="w9P-yZ-pho" secondAttribute="bottom" constant="8" id="8ET-Mt-gF3"/>
|
||||
<constraint firstAttribute="bottom" secondItem="aWW-9r-3lC" secondAttribute="bottom" constant="19" id="8wP-dc-ILG"/>
|
||||
<constraint firstAttribute="trailing" secondItem="aWW-9r-3lC" secondAttribute="trailing" constant="3" id="Lhf-xZ-vWk"/>
|
||||
<constraint firstItem="JMN-i9-vxR" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="7" id="O8w-Nb-paE"/>
|
||||
<constraint firstItem="aWW-9r-3lC" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="20" id="QgG-WW-zbV"/>
|
||||
<constraint firstAttribute="bottom" secondItem="JiF-Nx-dl5" secondAttribute="bottom" constant="7" id="SIi-FU-8f2"/>
|
||||
<constraint firstItem="aWW-9r-3lC" firstAttribute="leading" secondItem="w9P-yZ-pho" secondAttribute="trailing" constant="8" id="dQs-ek-ECt"/>
|
||||
<constraint firstItem="w9P-yZ-pho" firstAttribute="leading" secondItem="JiF-Nx-dl5" secondAttribute="trailing" constant="13" id="fQn-oM-uvI"/>
|
||||
<constraint firstItem="aWW-9r-3lC" firstAttribute="leading" secondItem="JMN-i9-vxR" secondAttribute="trailing" constant="8" id="kgo-T3-47B"/>
|
||||
<constraint firstItem="JiF-Nx-dl5" firstAttribute="leading" secondItem="moN-VP-hzI" secondAttribute="leading" constant="3" id="lYV-gy-fqI"/>
|
||||
<constraint firstItem="w9P-yZ-pho" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="29" id="moi-p4-d9X"/>
|
||||
<constraint firstItem="JMN-i9-vxR" firstAttribute="leading" secondItem="JiF-Nx-dl5" secondAttribute="trailing" constant="13" id="p3K-7u-mdM"/>
|
||||
<constraint firstAttribute="bottom" secondItem="JMN-i9-vxR" secondAttribute="bottom" constant="21" id="sYy-ZF-GpO"/>
|
||||
<constraint firstItem="JiF-Nx-dl5" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="7" id="wcd-hM-fV6"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="imageView" destination="JiF-Nx-dl5" id="pVf-M3-mAH"/>
|
||||
|
|
|
@ -34,20 +34,6 @@
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-(void)windowDidLoad
|
||||
{
|
||||
//super
|
||||
[super windowDidLoad];
|
||||
|
||||
//load whitelisted items
|
||||
self.items = [NSMutableArray arrayWithContentsOfFile:[[APP_SUPPORT_DIRECTORY stringByExpandingTildeInPath] stringByAppendingPathComponent:FILE_WHITELIST]];
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
//table delegate
|
||||
// ->return number of rows
|
||||
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
||||
|
@ -75,6 +61,9 @@
|
|||
//app bundle
|
||||
NSBundle* appBundle = nil;
|
||||
|
||||
//device type
|
||||
NSString* device = nil;
|
||||
|
||||
//sanity check
|
||||
if(row >= self.items.count)
|
||||
{
|
||||
|
@ -83,7 +72,7 @@
|
|||
}
|
||||
|
||||
//grab process path
|
||||
processPath = [self.items objectAtIndex:row];
|
||||
processPath = [[self.items objectAtIndex:row] objectForKey:EVENT_PROCESS_PATH];
|
||||
|
||||
//try find an app bundle
|
||||
appBundle = findAppBundle(processPath);
|
||||
|
@ -104,6 +93,19 @@
|
|||
//grab icon
|
||||
processIcon = getIconForProcess(processPath);
|
||||
|
||||
//set device type for audio
|
||||
if(SOURCE_AUDIO.intValue == [[[self.items objectAtIndex:row] objectForKey:EVENT_DEVICE] intValue])
|
||||
{
|
||||
//set
|
||||
device = @"mic";
|
||||
}
|
||||
//set device type for mic
|
||||
else if(SOURCE_VIDEO.intValue == [[[self.items objectAtIndex:row] objectForKey:EVENT_DEVICE] intValue])
|
||||
{
|
||||
//set
|
||||
device = @"camera";
|
||||
}
|
||||
|
||||
//init table cell
|
||||
tableCell = [tableView makeViewWithIdentifier:@"itemCell" owner:self];
|
||||
if(nil == tableCell)
|
||||
|
@ -116,7 +118,8 @@
|
|||
tableCell.imageView.image = processIcon;
|
||||
|
||||
//set (main) text
|
||||
tableCell.textField.stringValue = processName;
|
||||
// process name (device)
|
||||
tableCell.textField.stringValue = [NSString stringWithFormat:@"%@ (access: %@)", processName, device];
|
||||
|
||||
//set sub text
|
||||
[[tableCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:processPath];
|
||||
|
@ -166,27 +169,39 @@ bail:
|
|||
//index of selected row
|
||||
NSInteger selectedRow = 0;
|
||||
|
||||
//item
|
||||
NSDictionary* item = nil;
|
||||
|
||||
//rule
|
||||
NSString* processPath = nil;
|
||||
|
||||
//device
|
||||
NSNumber* device = nil;
|
||||
|
||||
//grab selected row
|
||||
selectedRow = [self.tableView rowForView:sender];
|
||||
|
||||
//extract selected item
|
||||
processPath = self.items[selectedRow];
|
||||
|
||||
//grab item
|
||||
item = self.items[selectedRow];
|
||||
|
||||
//extract path
|
||||
processPath = item[EVENT_PROCESS_PATH];
|
||||
|
||||
//extract device
|
||||
device = item[EVENT_DEVICE];
|
||||
|
||||
//remove from items
|
||||
[self.items removeObject:processPath];
|
||||
[self.items removeObject:item];
|
||||
|
||||
//reload table
|
||||
[self.tableView reloadData];
|
||||
|
||||
//restart login item in background
|
||||
// ->pass in process name so it can un-whitelist via XPC
|
||||
// ->pass in process path/device so it can un-whitelist via XPC
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^{
|
||||
//restart
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) startLoginItem:YES args:@[processPath]];
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) startLoginItem:YES args:@[processPath, [device stringValue]]];
|
||||
});
|
||||
|
||||
return;
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
//sample binary
|
||||
#define SAMPLE @"/usr/bin/sample"
|
||||
|
||||
//path to siri
|
||||
#define SIRI @"/System/Library/PrivateFrameworks/AssistantServices.framework/assistantd"
|
||||
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
|
|
|
@ -388,13 +388,50 @@ bail:
|
|||
//assign
|
||||
candidateAudioProcs = [[intersection allObjects] mutableCopy];
|
||||
|
||||
//if there aren't any new i/o registy clients and only one new mach sender
|
||||
// ->use that! (e.g. Siri, reactivated)
|
||||
if( (0 == candidateAudioProcs.count) &&
|
||||
(1 == newSenders.count) )
|
||||
//if there aren't any new i/o registy clients might just be siri
|
||||
if(0 == candidateAudioProcs.count)
|
||||
{
|
||||
//assign as candidate
|
||||
[candidateAudioProcs addObject:newSenders.firstObject];
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, @"no new user clients");
|
||||
#endif
|
||||
|
||||
//1 new mach msg sender
|
||||
// just use that as candidate
|
||||
if(1 == newSenders.count)
|
||||
{
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, @"but only found one new mach sender, so using that!");
|
||||
#endif
|
||||
|
||||
//assign as candidate
|
||||
[candidateAudioProcs addObject:newSenders.firstObject];
|
||||
}
|
||||
|
||||
//more than
|
||||
// ->check if any are siri ('assisantd')?
|
||||
else
|
||||
{
|
||||
//check each new ones
|
||||
for(NSNumber* newSender in newSenders)
|
||||
{
|
||||
//check each
|
||||
if(YES == [SIRI isEqualToString:getProcessPath([newSender intValue])])
|
||||
{
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, @"found a mach sender that's 'siri' so using that!");
|
||||
#endif
|
||||
|
||||
//assign as candidate
|
||||
[candidateAudioProcs addObject:newSenders.firstObject];
|
||||
|
||||
//all set
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
|
@ -413,6 +450,7 @@ bail:
|
|||
goto bail;
|
||||
}
|
||||
|
||||
//got more than one candidate
|
||||
// ->invoke 'sample' to determine which candidate is using CMIO/video inputs
|
||||
// note: will skip FaceTime.app on macOS Sierra, as it doesn't do CMIO stuff directly
|
||||
audioProcs = [self sampleCandidates:candidateAudioProcs];
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
}
|
||||
|
||||
//whitelist a process
|
||||
-(void)whitelistProcess:(NSString*)processPath reply:(void (^)(BOOL))reply
|
||||
-(void)whitelistProcess:(NSString*)processPath device:(NSNumber*)device reply:(void (^)(BOOL))reply
|
||||
{
|
||||
//flag
|
||||
BOOL wasAdded = NO;
|
||||
|
@ -106,7 +106,7 @@
|
|||
}
|
||||
|
||||
//add
|
||||
[whiteList addObject:processPath];
|
||||
[whiteList addObject:@{EVENT_PROCESS_PATH:processPath, EVENT_DEVICE:device}];
|
||||
|
||||
//check if intermediate dirs exist
|
||||
// ->create them if they aren't there yet
|
||||
|
@ -151,7 +151,7 @@ bail:
|
|||
}
|
||||
|
||||
//remove a process from the whitelist file
|
||||
-(void)unWhitelistProcess:(NSString*)processPath reply:(void (^)(BOOL))reply
|
||||
-(void)unWhitelistProcess:(NSString*)processPath device:(NSNumber*)device reply:(void (^)(BOOL))reply
|
||||
{
|
||||
//flag
|
||||
BOOL wasRemoved = NO;
|
||||
|
@ -162,6 +162,11 @@ bail:
|
|||
//whitelist
|
||||
NSMutableArray* whiteList = nil;
|
||||
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"got request to unwhitelist %@/%@", processPath, device]);
|
||||
#endif
|
||||
|
||||
//init path to whitelist
|
||||
path = [[APP_SUPPORT_DIRECTORY stringByExpandingTildeInPath] stringByAppendingPathComponent:FILE_WHITELIST];
|
||||
|
||||
|
@ -176,22 +181,40 @@ bail:
|
|||
goto bail;
|
||||
}
|
||||
|
||||
//remove item
|
||||
[whiteList removeObject:processPath];
|
||||
|
||||
//save to disk
|
||||
if(YES != [whiteList writeToFile:path atomically:YES])
|
||||
//find/remove item from whitelist
|
||||
for(NSDictionary* item in whiteList)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"XPC: failed to save updated whitelist to %@", path]);
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
//match path and device?
|
||||
if( (YES == [item[EVENT_PROCESS_PATH] isEqualToString:processPath]) &&
|
||||
([item[EVENT_DEVICE] intValue] == device.intValue) )
|
||||
{
|
||||
//dbg msg
|
||||
#ifdef DEBUG
|
||||
logMsg(LOG_DEBUG, @"found match in whitelist, will remove!");
|
||||
#endif
|
||||
|
||||
//remove
|
||||
// ->ok, since we aren't going to iterate any more
|
||||
[whiteList removeObject:item];
|
||||
|
||||
//save to disk
|
||||
if(YES != [whiteList writeToFile:path atomically:YES])
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"XPC: failed to save updated whitelist to %@", path]);
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//happy
|
||||
wasRemoved = YES;
|
||||
|
||||
//done
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
||||
//happy
|
||||
wasRemoved = YES;
|
||||
|
||||
//bail
|
||||
bail:
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
|
||||
<rect key="frame" x="280" y="11" width="128" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="more info" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
|
||||
<buttonCell key="cell" type="push" title="More Info" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
|
@ -54,7 +54,7 @@
|
|||
<button verticalHuggingPriority="750" fixedFrame="YES" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="xnd-Gw-0o8">
|
||||
<rect key="frame" x="137" y="11" width="128" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="support us!" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6g3-Pg-x3P">
|
||||
<buttonCell key="cell" type="push" title="Support Us!" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6g3-Pg-x3P">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
|
|
|
@ -29,10 +29,10 @@
|
|||
-(void)updateAudioStatus:(unsigned int)status reply:(void (^)(void))reply;
|
||||
|
||||
//whitelist a process
|
||||
-(void)whitelistProcess:(NSString*)processPath reply:(void (^)(BOOL))reply;
|
||||
-(void)whitelistProcess:(NSString*)processPath device:(NSNumber*)device reply:(void (^)(BOOL))reply;
|
||||
|
||||
//remove a process from the whitelist file
|
||||
-(void)unWhitelistProcess:(NSString*)processPath reply:(void (^)(BOOL))reply;
|
||||
-(void)unWhitelistProcess:(NSString*)processPath device:(NSNumber*)device reply:(void (^)(BOOL))reply;
|
||||
|
||||
//kill a process
|
||||
-(void)killProcess:(NSNumber*)processID reply:(void (^)(BOOL))reply;
|
||||
|
|
Loading…
Reference in New Issue