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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,8 +20,6 @@
@synthesize avMonitor; @synthesize avMonitor;
@synthesize processPath; @synthesize processPath;
//@synthesize versionLabel;
//automatically called when nib is loaded //automatically called when nib is loaded
// ->center window // ->center window
-(void)awakeFromNib -(void)awakeFromNib
@ -31,7 +29,7 @@
} }
//automatically invoked when window is loaded //automatically invoked when window is loaded
// ->set to white // ->set to window to white
-(void)windowDidLoad -(void)windowDidLoad
{ {
//super //super
@ -40,9 +38,6 @@
//make white //make white
[self.window setBackgroundColor: NSColor.whiteColor]; [self.window setBackgroundColor: NSColor.whiteColor];
//set version sting
//[self.versionLabel setStringValue:[NSString stringWithFormat:@"version: %@", getAppVersion()]];
return; return;
} }
@ -156,4 +151,24 @@ bail:
return; 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 @end

View File

@ -8,11 +8,11 @@
#import "Consts.h" #import "Consts.h"
#import "Logging.h" #import "Logging.h"
#import "Utilities.h"
#import "AppDelegate.h" #import "AppDelegate.h"
#import "XPCProtocol.h" #import "XPCProtocol.h"
#import "StatusBarMenu.h" #import "StatusBarMenu.h"
#import <CoreMediaIO/CMIOHardware.h> #import <CoreMediaIO/CMIOHardware.h>
#import <AVFoundation/AVFoundation.h> #import <AVFoundation/AVFoundation.h>
@ -239,14 +239,17 @@
//resume //resume
[xpcConnection resume]; [xpcConnection resume];
//tell XPC about audio status //tell XPC to exit
// ->for example, when audio is active, will stop baselining
[[xpcConnection remoteObjectProxy] exit]; [[xpcConnection remoteObjectProxy] exit];
//give it a sec for XPC msg to go thru //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]; [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! //bye!
[[NSApplication sharedApplication] terminate:nil]; [[NSApplication sharedApplication] terminate:nil];

View File

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

View File

@ -144,8 +144,12 @@
</subviews> </subviews>
<constraints> <constraints>
<constraint firstItem="gth-To-Lf2" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="-1" id="0Jc-HW-sRY"/> <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 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="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"/> <constraint firstItem="gth-To-Lf2" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="-1" id="jrL-0c-zSr"/>
</constraints> </constraints>
</view> </view>

View File

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

View File

@ -161,7 +161,7 @@ static NSArray* ignoredProcs = nil;
} }
//enumerate all (recent) process that appear to be using video //enumerate all (recent) process that appear to be using video
-(NSMutableArray*)enumVideoProcs -(NSMutableArray*)enumVideoProcs:(BOOL)polling
{ {
//current procs //current procs
NSMutableArray* videoProcs = nil; NSMutableArray* videoProcs = nil;
@ -176,6 +176,9 @@ static NSArray* ignoredProcs = nil;
//pid of camera assistant process //pid of camera assistant process
pid_t cameraAssistant = 0; pid_t cameraAssistant = 0;
//'frontmost' application
pid_t activeApp = -1;
//alloc //alloc
candidateVideoProcs = [NSMutableArray array]; candidateVideoProcs = [NSMutableArray array];
@ -237,6 +240,30 @@ static NSArray* ignoredProcs = nil;
//update //update
self.machSendersVideo = currentSenders; 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 //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 // ->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 of coreaudio process
pid_t coreAudio = 0; pid_t coreAudio = 0;
//'frontmost' application
pid_t activeApp = -1;
//alloc array //alloc array
newSenders = [NSMutableArray array]; newSenders = [NSMutableArray array];
@ -439,9 +469,9 @@ bail:
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"found %lu candidate audio procs: %@", (unsigned long)candidateAudioProcs.count, candidateAudioProcs]); logMsg(LOG_DEBUG, [NSString stringWithFormat:@"found %lu candidate audio procs: %@", (unsigned long)candidateAudioProcs.count, candidateAudioProcs]);
#endif #endif
//only once candidate? //only one candidate?
// ->all set, so assign, then bail here // ->all set, so assign, then bail here
if(candidateAudioProcs.count <= 1) if(1 == candidateAudioProcs.count)
{ {
//assign //assign
audioProcs = candidateAudioProcs; audioProcs = candidateAudioProcs;
@ -449,8 +479,31 @@ bail:
//bail //bail
goto 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 // ->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 // note: will skip FaceTime.app on macOS Sierra, as it doesn't do CMIO stuff directly
audioProcs = [self sampleCandidates:candidateAudioProcs]; audioProcs = [self sampleCandidates:candidateAudioProcs];

View File

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

View File

@ -33,10 +33,10 @@
} }
//call into emumerate to get (new) video proc //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 w/ video procs
reply([[Enumerator sharedManager] enumVideoProcs]); reply([[Enumerator sharedManager] enumVideoProcs:polling]);
return; return;
} }

View File

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

View File

@ -1127,3 +1127,10 @@ void makeTextViewHyperlink(NSTextField* textField, NSURL* url)
return; 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; -(void)getAudioProcs:(void (^)(NSMutableArray *))reply;
//get (new) video procs //get (new) video procs
-(void)getVideoProcs:(void (^)(NSMutableArray *))reply; -(void)getVideoProcs:(BOOL)polling reply:(void (^)(NSMutableArray *))reply;
//update status video //update status video
// ->allows enumerator to stop baselining (when active), etc // ->allows enumerator to stop baselining (when active), etc