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.
This commit is contained in:
Kyle Neideck 2017-06-22 19:22:24 +10:00
parent 5a657a01a6
commit c907f13554
No known key found for this signature in database
GPG key ID: CAA8D9B8E39EC18C
2 changed files with 43 additions and 4 deletions

View file

@ -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 <NSObject>
- (void) setUpWithApp:(NSRunningApplication*)app context:(BGMAppVolumes*)ctx menuItem:(NSMenuItem*)item;
- (void) setUpWithApp:(NSRunningApplication*)app
context:(BGMAppVolumes*)ctx
menuItem:(NSMenuItem*)item;
@end

View file

@ -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<NSString*>*) responsibleBundleIDsOf:(NSString*)parentBundleID {
NSDictionary<NSString*, NSArray<NSString*>*>* 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