improved "disable" logic

This commit is contained in:
Patrick Wardle 2021-05-05 23:26:45 -07:00
parent 0ce6562493
commit b637588228
4 changed files with 78 additions and 14 deletions

View File

@ -10,6 +10,11 @@
@import Foundation; @import Foundation;
@import UserNotifications; @import UserNotifications;
#import <CoreAudio/CoreAudio.h>
#import <CoreMedia/CoreMedia.h>
#import <Foundation/Foundation.h>
#import <CoreMediaIO/CMIOHardware.h>
#import "LogMonitor.h" #import "LogMonitor.h"
@interface AVMonitor : NSObject <UNUserNotificationCenterDelegate> @interface AVMonitor : NSObject <UNUserNotificationCenterDelegate>
@ -26,6 +31,9 @@
//audio clients //audio clients
@property(nonatomic, retain)NSMutableArray* audioClients; @property(nonatomic, retain)NSMutableArray* audioClients;
//audio (mic) callback
@property(nonatomic, copy)AudioObjectPropertyListenerBlock listenerBlock;
//camera state //camera state
@property NSControlStateValue cameraState; @property NSControlStateValue cameraState;

View File

@ -14,11 +14,6 @@
#import "AVMonitor.h" #import "AVMonitor.h"
#import "utilities.h" #import "utilities.h"
#import <CoreAudio/CoreAudio.h>
#import <CoreMedia/CoreMedia.h>
#import <Foundation/Foundation.h>
#import <CoreMediaIO/CMIOHardware.h>
/* GLOBALS */ /* GLOBALS */
@ -812,9 +807,12 @@ bail:
//init property struct's element //init property struct's element
propertyStruct.mElement = kAudioObjectPropertyElementMaster; propertyStruct.mElement = kAudioObjectPropertyElementMaster;
//weak self
__unsafe_unretained typeof(self)weakSelf = self;
//block //block
// invoked when audio changes // invoked when audio changes
AudioObjectPropertyListenerBlock listenerBlock = ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses) self.listenerBlock = ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses)
{ {
//state //state
NSInteger state = -1; NSInteger state = -1;
@ -834,13 +832,13 @@ bail:
os_log_debug(logHandle, "ignoring mic event, as it happened <0.5s "); os_log_debug(logHandle, "ignoring mic event, as it happened <0.5s ");
//update //update
self.lastMicEvent = [NSDate date]; weakSelf.lastMicEvent = [NSDate date];
return; return;
} }
//update //update
self.lastMicEvent = [NSDate date]; weakSelf.lastMicEvent = [NSDate date];
//mic off? //mic off?
if(NSControlStateValueOff == state) if(NSControlStateValueOff == state)
@ -849,15 +847,15 @@ bail:
os_log_debug(logHandle, "built in mic turned to off"); os_log_debug(logHandle, "built in mic turned to off");
//show notification //show notification
[self generateNotification:Device_Microphone state:NSControlStateValueOff client:nil]; [weakSelf generateNotification:Device_Microphone state:NSControlStateValueOff client:nil];
//execute action //execute action
[self executeUserAction:Device_Microphone state:NSControlStateValueOn client:nil]; [weakSelf executeUserAction:Device_Microphone state:NSControlStateValueOn client:nil];
} }
}; };
//add property listener for audio changes //add property listener for audio changes
status = AudioObjectAddPropertyListenerBlock(builtInMic, &propertyStruct, dispatch_get_main_queue(), listenerBlock); status = AudioObjectAddPropertyListenerBlock(builtInMic, &propertyStruct, dispatch_get_main_queue(), self.listenerBlock);
if(noErr != status) if(noErr != status)
{ {
//err msg //err msg
@ -875,6 +873,49 @@ bail:
return bRegistered; return bRegistered;
} }
//stop audio monitor
-(void)stopAudioMonitor
{
//status
OSStatus status = -1;
//built in mic
AudioObjectID builtInMic = 0;
//property struct
AudioObjectPropertyAddress propertyStruct = {0};
//dbg msg
os_log_debug(logHandle, "stopping audio (device) monitor");
//init property struct's selector
propertyStruct.mSelector = kAudioDevicePropertyDeviceIsRunningSomewhere;
//init property struct's scope
propertyStruct.mScope = kAudioObjectPropertyScopeGlobal;
//init property struct's element
propertyStruct.mElement = kAudioObjectPropertyElementMaster;
//find built-in mic
builtInMic = [self findBuiltInMic];
if(0 != builtInMic)
{
//remove
status = AudioObjectRemovePropertyListenerBlock(builtInMic, &propertyStruct, dispatch_get_main_queue(), self.listenerBlock);
if(noErr != status)
{
//err msg
os_log_error(logHandle, "ERROR: 'AudioObjectRemovePropertyListenerBlock' failed with %d", status);
}
}
bail:
return;
}
//determine if audio device is active //determine if audio device is active
-(UInt32)getMicState:(AudioObjectID)deviceID -(UInt32)getMicState:(AudioObjectID)deviceID
{ {
@ -1116,6 +1157,9 @@ bail:
//stop audio log monitoring //stop audio log monitoring
[self.audioLogMonitor stop]; [self.audioLogMonitor stop];
//stop audio (device) monitor
[self stopAudioMonitor];
return; return;
} }

View File

@ -39,6 +39,9 @@ extern os_log_t logHandle;
//flag //flag
BOOL autoLaunched = NO; BOOL autoLaunched = NO;
//init
self.avMonitor = [[AVMonitor alloc] init];
//get real parent //get real parent
parent = getRealParent(getpid()); parent = getRealParent(getpid());
@ -68,9 +71,6 @@ extern os_log_t logHandle;
// kick off device monitoring // kick off device monitoring
if(YES != [NSUserDefaults.standardUserDefaults boolForKey:PREF_IS_DISABLED]) if(YES != [NSUserDefaults.standardUserDefaults boolForKey:PREF_IS_DISABLED])
{ {
//init
self.avMonitor = [[AVMonitor alloc] init];
//start //start
[self.avMonitor start]; [self.avMonitor start];
} }

View File

@ -204,9 +204,21 @@ enum menuItems
//stop monitor //stop monitor
if(YES == self.isDisabled) if(YES == self.isDisabled)
{ {
//dbg msg
os_log_debug(logHandle, "will stop monitor");
//stop //stop
[((AppDelegate*)[[NSApplication sharedApplication] delegate]).avMonitor stop]; [((AppDelegate*)[[NSApplication sharedApplication] delegate]).avMonitor stop];
} }
//(re)start monitor
else
{
//dbg msg
os_log_debug(logHandle, "will (re)start monitor");
//start
[((AppDelegate*)[[NSApplication sharedApplication] delegate]).avMonitor start];
}
break; break;