This commit is contained in:
Patrick Wardle 2017-09-24 20:29:24 -10:00
parent 5bc2adc510
commit 027d0840ed
16 changed files with 145 additions and 47 deletions

View File

@ -41,7 +41,7 @@
#endif
//stop
// ->kill login item/XPC service
// ->kill main app/login item/XPC service
[self stop];
//uninstall
@ -315,6 +315,9 @@ bail:
//stop
-(void)stop
{
//kill main app
execTask(PKILL, @[[APP_NAME stringByDeletingPathExtension]], YES);
//kill helper app
execTask(PKILL, @[APP_HELPER], YES);

View File

@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.1</string>
<string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.1.1</string>
<string>1.1.2</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>

View File

@ -46,8 +46,8 @@
//monitor thread
@property(nonatomic, retain)NSThread* videoMonitorThread;
//remember popup/window controller
@property(nonatomic, retain)RememberWindowController* rememberWindowController;
//popup windows
@property(nonatomic, retain)NSMutableArray* rememberPopups;
//last event
@property(nonatomic, retain)NSDictionary* lastEvent;

View File

@ -21,10 +21,10 @@
@synthesize lastEvent;
@synthesize whiteList;
@synthesize audioActive;
@synthesize rememberPopups;
@synthesize activationAlerts;
@synthesize lastNotification;
@synthesize videoMonitorThread;
@synthesize rememberWindowController;
//init
-(id)init
@ -36,6 +36,9 @@
//alloc
activationAlerts = [NSMutableDictionary dictionary];
//alloc
rememberPopups = [NSMutableArray array];
//load whitelist
[self loadWhitelist];
}
@ -568,10 +571,10 @@ bail:
//set allowed classes
[xpcConnection.remoteObjectInterface setClasses: [NSSet setWithObjects: [NSMutableArray class], [NSNumber class], nil]
forSelector: @selector(getVideoProcs:) argumentIndex: 0 ofReply: YES];
forSelector: @selector(getVideoProcs:reply:) argumentIndex: 0 ofReply: YES];
//invoke XPC service
[[xpcConnection remoteObjectProxy] getVideoProcs:^(NSMutableArray* videoProcesses)
[[xpcConnection remoteObjectProxy] getVideoProcs:NO reply:^(NSMutableArray* videoProcesses)
{
//close connection
[xpcConnection invalidate];
@ -1279,7 +1282,7 @@ bail:
#endif
//delay, then close
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
//close
[NSUserNotificationCenter.defaultUserNotificationCenter removeDeliveredNotification:notification];
@ -1319,6 +1322,9 @@ bail:
//log msg
NSMutableString* logMessage = nil;
//remember popup/window controller
RememberWindowController* rememberWindowController = nil;
//always (manually) load preferences
preferences = [NSDictionary dictionaryWithContentsOfFile:[APP_PREFERENCES stringByExpandingTildeInPath]];
@ -1442,29 +1448,33 @@ bail:
//bail
goto bail;
}
//alloc/init settings window
if(nil == self.rememberWindowController)
{
//alloc/init
rememberWindowController = [[RememberWindowController alloc] initWithWindowNibName:@"RememberPopup"];
}
//alloc/init
rememberWindowController = [[RememberWindowController alloc] initWithWindowNibName:@"RememberPopup"];
//center window
[[self.rememberWindowController window] center];
[[rememberWindowController window] center];
//show it
[self.rememberWindowController showWindow:self];
[rememberWindowController showWindow:self];
//manually configure
// ->invoke here as the outlets will be set
[self.rememberWindowController configure:notification avMonitor:self];
[rememberWindowController configure:notification avMonitor:self];
//make it key window
[self.rememberWindowController.window makeKeyAndOrderFront:self];
[rememberWindowController.window makeKeyAndOrderFront:self];
//make window front
[NSApp activateIgnoringOtherApps:YES];
//save reference to window
// ->otherwise memory is freed/window not shown :/
@synchronized (self)
{
//save
[self.rememberPopups addObject:rememberWindowController];
}
}
//when user clicks 'block'
@ -1620,7 +1630,7 @@ bail:
//set classes
// ->arrays/numbers ok to vend
[xpcConnection.remoteObjectInterface setClasses: [NSSet setWithObjects: [NSMutableArray class], [NSNumber class], nil]
forSelector: @selector(getVideoProcs:) argumentIndex: 0 ofReply: YES];
forSelector: @selector(getVideoProcs:reply:) argumentIndex: 0 ofReply: YES];
//resume
[xpcConnection resume];
@ -1637,7 +1647,7 @@ bail:
//invoke XPC service to get (new) video procs
// ->will generate user notifications for any new processes
[[xpcConnection remoteObjectProxy] getVideoProcs:^(NSMutableArray* videoProcesses)
[[xpcConnection remoteObjectProxy] getVideoProcs:YES reply:^(NSMutableArray* videoProcesses)
{
//dbg msg
#ifdef DEBUG

View File

@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.1</string>
<string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.1.1</string>
<string>1.1.2</string>
<key>LSUIElement</key>
<true/>
<key>LSMinimumSystemVersion</key>

View File

@ -20,8 +20,6 @@
@synthesize avMonitor;
@synthesize processPath;
//@synthesize versionLabel;
//automatically called when nib is loaded
// ->center window
-(void)awakeFromNib
@ -31,7 +29,7 @@
}
//automatically invoked when window is loaded
// ->set to white
// ->set to window to white
-(void)windowDidLoad
{
//super
@ -40,9 +38,6 @@
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//set version sting
//[self.versionLabel setStringValue:[NSString stringWithFormat:@"version: %@", getAppVersion()]];
return;
}
@ -156,4 +151,24 @@ bail:
return;
}
//automatically invoked when window is closing
// ->remove self from array
-(void)windowWillClose:(NSNotification *)notification
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, @"window is closing, will remove array reference");
#endif
//sync to remove
@synchronized (self.avMonitor) {
//remove
[self.avMonitor.rememberPopups removeObject:self];
}
return;
}
@end

View File

@ -8,11 +8,11 @@
#import "Consts.h"
#import "Logging.h"
#import "Utilities.h"
#import "AppDelegate.h"
#import "XPCProtocol.h"
#import "StatusBarMenu.h"
#import <CoreMediaIO/CMIOHardware.h>
#import <AVFoundation/AVFoundation.h>
@ -239,14 +239,17 @@
//resume
[xpcConnection resume];
//tell XPC about audio status
// ->for example, when audio is active, will stop baselining
//tell XPC to exit
[[xpcConnection remoteObjectProxy] exit];
//give it a sec for XPC msg to go thru
// ->can't wait on XPC since its killing itself!
// ->don't wait on XPC since its killing itself!
[NSThread sleepForTimeInterval:0.10f];
//kill main (preference) app
// ->might be open, and looks odd if its still present
execTask(PKILL, @[[APP_NAME stringByDeletingPathExtension]], YES);
//bye!
[[NSApplication sharedApplication] terminate:nil];

View File

@ -15,11 +15,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.1</string>
<string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.1.1</string>
<string>1.1.2</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key>

View File

@ -144,8 +144,12 @@
</subviews>
<constraints>
<constraint firstItem="gth-To-Lf2" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="-1" id="0Jc-HW-sRY"/>
<constraint firstAttribute="bottom" secondItem="gth-To-Lf2" secondAttribute="bottom" constant="-1" id="1XM-Vv-cJW"/>
<constraint firstAttribute="trailing" secondItem="gth-To-Lf2" secondAttribute="trailing" constant="-1" id="GjA-Ta-LSr"/>
<constraint firstItem="gth-To-Lf2" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="-1" id="ehW-gX-Et6"/>
<constraint firstAttribute="bottom" secondItem="gth-To-Lf2" secondAttribute="bottom" constant="-1" id="gFc-Mm-n7w"/>
<constraint firstAttribute="trailing" secondItem="gth-To-Lf2" secondAttribute="trailing" constant="-1" id="ga8-g4-rt6"/>
<constraint firstItem="gth-To-Lf2" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="-1" id="gtf-7O-hid"/>
<constraint firstItem="gth-To-Lf2" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="-1" id="jrL-0c-zSr"/>
</constraints>
</view>

View File

@ -64,7 +64,7 @@
-(NSMutableArray*)enumAudioProcs;
//enumerate all (recent) process that appear to be using video
-(NSMutableArray*)enumVideoProcs;
-(NSMutableArray*)enumVideoProcs:(BOOL)polling;
//set status of audio
-(void)updateAudioStatus:(BOOL)isEnabled;

View File

@ -161,7 +161,7 @@ static NSArray* ignoredProcs = nil;
}
//enumerate all (recent) process that appear to be using video
-(NSMutableArray*)enumVideoProcs
-(NSMutableArray*)enumVideoProcs:(BOOL)polling
{
//current procs
NSMutableArray* videoProcs = nil;
@ -176,6 +176,9 @@ static NSArray* ignoredProcs = nil;
//pid of camera assistant process
pid_t cameraAssistant = 0;
//'frontmost' application
pid_t activeApp = -1;
//alloc
candidateVideoProcs = [NSMutableArray array];
@ -237,6 +240,30 @@ static NSArray* ignoredProcs = nil;
//update
self.machSendersVideo = currentSenders;
//didn't find any?
// ->when not polling, add foreground process (and sample it below)
if( (0 == candidateVideoProcs.count) &&
(YES != polling))
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, @"didn't find any candidate video apps, and not polling, so will grab (and sample) active application");
#endif
//get active app
activeApp = frontmostApplication();
if(-1 != activeApp)
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"found active application: %d", activeApp]);
#endif
//add it
[candidateVideoProcs addObject:[NSNumber numberWithInt:activeApp]];
}
}
//invoke 'sample' to confirm that candidates are using CMIO/video inputs
// ->note, will skip FaceTime.app on macOS Sierra, as it doesn't do CMIO stuff directly
@ -278,6 +305,9 @@ bail:
//pid of coreaudio process
pid_t coreAudio = 0;
//'frontmost' application
pid_t activeApp = -1;
//alloc array
newSenders = [NSMutableArray array];
@ -439,9 +469,9 @@ bail:
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"found %lu candidate audio procs: %@", (unsigned long)candidateAudioProcs.count, candidateAudioProcs]);
#endif
//only once candidate?
//only one candidate?
// ->all set, so assign, then bail here
if(candidateAudioProcs.count <= 1)
if(1 == candidateAudioProcs.count)
{
//assign
audioProcs = candidateAudioProcs;
@ -449,8 +479,31 @@ bail:
//bail
goto bail;
}
//got more than one candidate
//still none
// ->add active app as candiate (and sample it, below)
if(0 == candidateAudioProcs.count)
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, @"didn't find any candidate audio apps, will grab (and sample) active application");
#endif
//get active app
activeApp = frontmostApplication();
if(-1 != activeApp)
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"found active application: %d", activeApp]);
#endif
//add it
[candidateAudioProcs addObject:[NSNumber numberWithInt:activeApp]];
}
}
//got one or more candidate application
// ->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];

View File

@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>1.1.1</string>
<string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.1.1</string>
<string>1.1.2</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) 2017 Objective-See. All rights reserved.</string>
<key>XPCService</key>

View File

@ -33,10 +33,10 @@
}
//call into emumerate to get (new) video proc
-(void)getVideoProcs:(void (^)(NSMutableArray *))reply
-(void)getVideoProcs:(BOOL)polling reply:(void (^)(NSMutableArray *))reply
{
//reply w/ video procs
reply([[Enumerator sharedManager] enumVideoProcs]);
reply([[Enumerator sharedManager] enumVideoProcs:polling]);
return;
}

View File

@ -80,4 +80,7 @@ pid_t findProcess(NSString* processName);
//convert a textview to a clickable hyperlink
void makeTextViewHyperlink(NSTextField* textField, NSURL* url);
//get active application
pid_t frontmostApplication();
#endif

View File

@ -1127,3 +1127,10 @@ void makeTextViewHyperlink(NSTextField* textField, NSURL* url)
return;
}
//get frontmost (active) app
pid_t frontmostApplication()
{
//get/ret
return NSWorkspace.sharedWorkspace.frontmostApplication.processIdentifier;
}

View File

@ -18,7 +18,7 @@
-(void)getAudioProcs:(void (^)(NSMutableArray *))reply;
//get (new) video procs
-(void)getVideoProcs:(void (^)(NSMutableArray *))reply;
-(void)getVideoProcs:(BOOL)polling reply:(void (^)(NSMutableArray *))reply;
//update status video
// ->allows enumerator to stop baselining (when active), etc