From c907f135541019ffe019bb489d9280f170794be8 Mon Sep 17 00:00:00 2001 From: Kyle Neideck Date: Thu, 22 Jun 2017 19:22:24 +1000 Subject: [PATCH] Partial fix for apps' bundle IDs not matching their HAL clients. Some apps have different bundle IDs to their CoreAudio clients, so the bundle ID BGMApp sends with the app's volume doesn't match any client in BGMDriver. This change hardcodes the bundle IDs used by some popular apps and the bundle IDs their clients use. We should be able to fix this for all (almost all?) apps at some point. --- BGMApp/BGMApp/BGMAppVolumes.h | 8 +++++-- BGMApp/BGMApp/BGMAppVolumes.mm | 39 ++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/BGMApp/BGMApp/BGMAppVolumes.h b/BGMApp/BGMApp/BGMAppVolumes.h index 7139f06..bda363a 100644 --- a/BGMApp/BGMApp/BGMAppVolumes.h +++ b/BGMApp/BGMApp/BGMAppVolumes.h @@ -29,7 +29,9 @@ @interface BGMAppVolumes : NSObject -- (id) initWithMenu:(NSMenu*)menu appVolumeView:(NSView*)view audioDevices:(BGMAudioDeviceManager*)audioDevices; +- (id) initWithMenu:(NSMenu*)menu + appVolumeView:(NSView*)view + audioDevices:(BGMAudioDeviceManager*)audioDevices; @end @@ -37,7 +39,9 @@ @protocol BGMAppVolumeMenuItemSubview -- (void) setUpWithApp:(NSRunningApplication*)app context:(BGMAppVolumes*)ctx menuItem:(NSMenuItem*)item; +- (void) setUpWithApp:(NSRunningApplication*)app + context:(BGMAppVolumes*)ctx + menuItem:(NSMenuItem*)item; @end diff --git a/BGMApp/BGMApp/BGMAppVolumes.mm b/BGMApp/BGMApp/BGMAppVolumes.mm index 79fe93a..1eab34f 100644 --- a/BGMApp/BGMApp/BGMAppVolumes.mm +++ b/BGMApp/BGMApp/BGMAppVolumes.mm @@ -324,6 +324,33 @@ static CGFloat const kAppVolumeViewInitialHeight = 20; [audioDevices bgmDevice].SetPropertyData_CFType(kBGMAppVolumesAddress, appVolumeChanges.AsPropertyList()); } +// This is a temporary solution that lets us control the volumes of some multiprocess apps, i.e. +// apps that play their audio from a process with a different bundle ID. +// +// We can't just check the child processes of the apps' main processes because they're usually +// created with launchd rather than being actual child processes. There's a private API to get the +// processes that an app is "responsible for", so we'll try to use it in the proper fix and only use +// this list if the API doesn't work. +// +// TODO: Consider moving the logic to a new class when we fix this issue properly so this class is +// only responsible for UI. ++ (NSArray*) responsibleBundleIDsOf:(NSString*)parentBundleID { + NSDictionary*>* bundleIDMap = @{ + // Safari + @"com.apple.Safari": @[@"com.apple.WebKit.WebContent"], + // Firefox + @"org.mozilla.firefox": @[@"org.mozilla.plugincontainer"], + // Firefox Nightly + @"org.mozilla.nightly": @[@"org.mozilla.plugincontainer"], + // VMWare Fusion + @"com.vmware.fusion": @[@"com.vmware.vmware-vmx"], + // MPlayer OSX Extended + @"hu.mplayerhq.mplayerosx.extended": @[@"ch.sttz.mplayerosx.extended.binaries.officialsvn"] + }; + + return bundleIDMap[parentBundleID]; +} + @end #pragma mark Custom Classes (IB) @@ -428,8 +455,12 @@ static CGFloat const kAppVolumeViewInitialHeight = 20; DebugMsg("BGMAppVolumes::appVolumeChanged: App volume for %s changed to %d", appBundleID.UTF8String, self.intValue); [self snap]; - + [context sendVolumeChangeToBGMDevice:self.intValue appProcessID:appProcessID appBundleID:appBundleID]; + + for (NSString* bundleID : [BGMAppVolumes responsibleBundleIDsOf:appBundleID]) { + [context sendVolumeChangeToBGMDevice:self.intValue appProcessID:-1 appBundleID:bundleID]; + } } @end @@ -471,8 +502,12 @@ static CGFloat const kAppVolumeViewInitialHeight = 20; // TODO: This (sending updates to the driver) should probably be rate-limited. It uses a fair bit of CPU for me. DebugMsg("BGMAppVolumes::appPanPositionChanged: App pan position for %s changed to %d", appBundleID.UTF8String, self.intValue); - + [context sendPanPositionChangeToBGMDevice:self.intValue appProcessID:appProcessID appBundleID:appBundleID]; + + for (NSString* bundleID : [BGMAppVolumes responsibleBundleIDsOf:appBundleID]) { + [context sendPanPositionChangeToBGMDevice:self.intValue appProcessID:-1 appBundleID:bundleID]; + } } @end