mirror of
https://github.com/kyleneideck/BackgroundMusic
synced 2024-11-10 06:34:22 +00:00
BGMApp: Move some more code into BGMBackgroundMusicDevice.
Mostly code for getting and setting BGMDevice's custom properties. Also adds some stricter checking for property data received from BGMDevice.
This commit is contained in:
parent
e05acde351
commit
02558cd275
8 changed files with 153 additions and 23 deletions
|
@ -98,7 +98,7 @@ static CGFloat const kAppVolumeViewInitialHeight = 20;
|
|||
#endif
|
||||
|
||||
// Get the app volumes currently set on the device
|
||||
CACFArray appVolumesOnDevice((CFArrayRef)[audioDevices bgmDevice].GetPropertyData_CFType(kBGMAppVolumesAddress), false);
|
||||
CACFArray appVolumesOnDevice((CFArrayRef)[audioDevices bgmDevice].GetAppVolumes(), false);
|
||||
|
||||
NSInteger index = [bgmMenu indexOfItemWithTag:kAppVolumesHeadingMenuItemTag] + 1;
|
||||
|
||||
|
|
|
@ -145,14 +145,7 @@ static Float32 const kUnpauseDelayWeightingFactor = 0.1f;
|
|||
}
|
||||
|
||||
- (BGMDeviceAudibleState) deviceAudibleState {
|
||||
BGMDeviceAudibleState audibleState;
|
||||
CFNumberRef audibleStateRef =
|
||||
static_cast<CFNumberRef>([audioDevices bgmDevice].GetPropertyData_CFType(kBGMAudibleStateAddress));
|
||||
|
||||
CFNumberGetValue(audibleStateRef, kCFNumberSInt32Type, &audibleState);
|
||||
CFRelease(audibleStateRef);
|
||||
|
||||
return audibleState;
|
||||
return [audioDevices bgmDevice].GetAudibleState();
|
||||
}
|
||||
|
||||
- (void) queuePauseBlock {
|
||||
|
|
|
@ -115,6 +115,20 @@ void BGMBackgroundMusicDevice::UnsetAsOSDefault(AudioDeviceID inOutputDeviceID)
|
|||
|
||||
#pragma mark App Volumes
|
||||
|
||||
CFArrayRef BGMBackgroundMusicDevice::GetAppVolumes() const
|
||||
{
|
||||
CFTypeRef appVolumes = GetPropertyData_CFType(kBGMAppVolumesAddress);
|
||||
|
||||
ThrowIfNULL(appVolumes,
|
||||
CAException(kAudioHardwareIllegalOperationError),
|
||||
"BGMBackgroundMusicDevice::GetAppVolumes: !appVolumes");
|
||||
ThrowIf(CFGetTypeID(appVolumes) != CFArrayGetTypeID(),
|
||||
CAException(kAudioHardwareIllegalOperationError),
|
||||
"BGMBackgroundMusicDevice::GetAppVolumes: Expected CFArray value");
|
||||
|
||||
return static_cast<CFArrayRef>(appVolumes);
|
||||
}
|
||||
|
||||
void BGMBackgroundMusicDevice::SetAppVolume(SInt32 inVolume,
|
||||
pid_t inAppProcessID,
|
||||
CFStringRef inAppBundleID)
|
||||
|
@ -226,5 +240,70 @@ BGMBackgroundMusicDevice::ResponsibleBundleIDsOf(CFStringRef inParentBundleID)
|
|||
return bundleIDMap[inParentBundleID];
|
||||
}
|
||||
|
||||
#pragma mark Audible State
|
||||
|
||||
BGMDeviceAudibleState BGMBackgroundMusicDevice::GetAudibleState() const
|
||||
{
|
||||
CFTypeRef propertyDataRef = GetPropertyData_CFType(kBGMAudibleStateAddress);
|
||||
|
||||
ThrowIfNULL(propertyDataRef,
|
||||
CAException(kAudioHardwareIllegalOperationError),
|
||||
"BGMBackgroundMusicDevice::GetAudibleState: !propertyDataRef");
|
||||
|
||||
ThrowIf(CFGetTypeID(propertyDataRef) != CFNumberGetTypeID(),
|
||||
CAException(kAudioHardwareIllegalOperationError),
|
||||
"BGMBackgroundMusicDevice::GetAudibleState: Property was not a CFNumber");
|
||||
|
||||
CFNumberRef audibleStateRef = static_cast<CFNumberRef>(propertyDataRef);
|
||||
|
||||
BGMDeviceAudibleState audibleState;
|
||||
Boolean success = CFNumberGetValue(audibleStateRef, kCFNumberSInt32Type, &audibleState);
|
||||
CFRelease(audibleStateRef);
|
||||
|
||||
ThrowIf(!success,
|
||||
CAException(kAudioHardwareIllegalOperationError),
|
||||
"BGMBackgroundMusicDevice::GetMusicPlayerProcessID: CFNumberGetValue failed");
|
||||
|
||||
return audibleState;
|
||||
}
|
||||
|
||||
#pragma mark Music Player
|
||||
|
||||
pid_t BGMBackgroundMusicDevice::GetMusicPlayerProcessID() const
|
||||
{
|
||||
CFTypeRef propertyDataRef = GetPropertyData_CFType(kBGMMusicPlayerProcessIDAddress);
|
||||
|
||||
ThrowIfNULL(propertyDataRef,
|
||||
CAException(kAudioHardwareIllegalOperationError),
|
||||
"BGMBackgroundMusicDevice::GetMusicPlayerProcessID: !propertyDataRef");
|
||||
|
||||
ThrowIf(CFGetTypeID(propertyDataRef) != CFNumberGetTypeID(),
|
||||
CAException(kAudioHardwareIllegalOperationError),
|
||||
"BGMBackgroundMusicDevice::GetMusicPlayerProcessID: Property was not a CFNumber");
|
||||
|
||||
CFNumberRef pidRef = static_cast<CFNumberRef>(propertyDataRef);
|
||||
|
||||
pid_t pid;
|
||||
Boolean success = CFNumberGetValue(pidRef, kCFNumberIntType, &pid);
|
||||
CFRelease(pidRef);
|
||||
|
||||
ThrowIf(!success,
|
||||
CAException(kAudioHardwareIllegalOperationError),
|
||||
"BGMBackgroundMusicDevice::GetMusicPlayerProcessID: CFNumberGetValue failed");
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
CFStringRef BGMBackgroundMusicDevice::GetMusicPlayerBundleID() const
|
||||
{
|
||||
CFStringRef bundleID = GetPropertyData_CFString(kBGMMusicPlayerBundleIDAddress);
|
||||
|
||||
ThrowIfNULL(bundleID,
|
||||
CAException(kAudioHardwareIllegalOperationError),
|
||||
"BGMBackgroundMusicDevice::GetMusicPlayerBundleID: !bundleID");
|
||||
|
||||
return bundleID;
|
||||
}
|
||||
|
||||
#pragma clang assume_nonnull end
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
// Superclass Includes
|
||||
#include "BGMAudioDevice.h"
|
||||
|
||||
// Local Includes
|
||||
#include "BGM_Types.h"
|
||||
|
||||
// STL Includes
|
||||
#include <vector>
|
||||
|
||||
|
@ -60,6 +63,7 @@ public:
|
|||
|
||||
#pragma mark Systemwide Default Device
|
||||
|
||||
public:
|
||||
/*!
|
||||
Set BGMDevice as the default audio device for all processes.
|
||||
|
||||
|
@ -75,6 +79,14 @@ public:
|
|||
|
||||
#pragma mark App Volumes
|
||||
|
||||
public:
|
||||
/*!
|
||||
@return The current value of BGMDevice's kAudioDeviceCustomPropertyAppVolumes property. See
|
||||
BGM_Types.h.
|
||||
@throws CAException If the HAL returns an error or a non-array type. Callers are responsible
|
||||
for validating and type-checking the values contained in the array.
|
||||
*/
|
||||
CFArrayRef GetAppVolumes() const;
|
||||
/*!
|
||||
@param inVolume A value between kAppRelativeVolumeMinRawValue and kAppRelativeVolumeMaxRawValue
|
||||
from BGM_Types.h. See kBGMAppVolumesKey_RelativeVolume in BGM_Types.h.
|
||||
|
@ -114,11 +126,60 @@ private:
|
|||
static std::vector<CFStringRef>
|
||||
ResponsibleBundleIDsOf(CFStringRef inParentBundleID);
|
||||
|
||||
#pragma mark Audible State
|
||||
|
||||
public:
|
||||
/*!
|
||||
@return BGMDevice's current "audible state", which can be either silent, silent except for the
|
||||
user's music player or audible, meaning a program other than the music player is
|
||||
playing audio.
|
||||
@throws CAException If the HAL returns an error or invalid data when queried.
|
||||
@see kAudioDeviceCustomPropertyDeviceAudibleState in BGM_Types.h.
|
||||
*/
|
||||
BGMDeviceAudibleState GetAudibleState() const;
|
||||
|
||||
#pragma mark Music Player
|
||||
|
||||
public:
|
||||
/*!
|
||||
@return The value of BGMDevice's property for the selected music player's process ID. Zero if
|
||||
the property is unset. (We assume kernel_task will never be the user's music player.)
|
||||
@throws CAException If the HAL returns an error or an invalid PID when queried.
|
||||
@see kAudioDeviceCustomPropertyMusicPlayerProcessID in BGM_Types.h.
|
||||
*/
|
||||
pid_t GetMusicPlayerProcessID() const;
|
||||
/*!
|
||||
Set the value of BGMDevice's property for the selected music player's process ID. Pass zero to
|
||||
unset the property. Setting this property will unset the bundle ID version of the property.
|
||||
|
||||
@throws CAException If the HAL returns an error.
|
||||
@see kAudioDeviceCustomPropertyMusicPlayerProcessID in BGM_Types.h.
|
||||
*/
|
||||
void SetMusicPlayerProcessID(CFNumberRef inProcessID) {
|
||||
SetPropertyData_CFType(kBGMMusicPlayerProcessIDAddress, inProcessID); }
|
||||
/*!
|
||||
@return The value of BGMDevice's property for the selected music player's bundle ID. The empty
|
||||
string if the property is unset.
|
||||
@throws CAException If the HAL returns an error or an invalid bundle ID when queried.
|
||||
@see kAudioDeviceCustomPropertyMusicPlayerBundleID in BGM_Types.h.
|
||||
*/
|
||||
CFStringRef GetMusicPlayerBundleID() const;
|
||||
/*!
|
||||
Set the value of BGMDevice's property for the selected music player's bundle ID. Pass the empty
|
||||
string to unset the property. Setting this property will unset the process ID version of the
|
||||
property.
|
||||
|
||||
@throws CAException If the HAL returns an error.
|
||||
@see kAudioDeviceCustomPropertyMusicPlayerBundleID in BGM_Types.h.
|
||||
*/
|
||||
void SetMusicPlayerBundleID(CFStringRef inBundleID) {
|
||||
SetPropertyData_CFString(kBGMMusicPlayerBundleIDAddress, inBundleID); }
|
||||
|
||||
#pragma mark UI Sounds Instance
|
||||
|
||||
public:
|
||||
/*! @return The instance of BGMDevice that handles UI sounds. */
|
||||
BGMAudioDevice GetUISoundsBGMDeviceInstance() const { return mUISoundsBGMDevice; }
|
||||
BGMAudioDevice GetUISoundsBGMDeviceInstance() { return mUISoundsBGMDevice; }
|
||||
|
||||
private:
|
||||
/*! The instance of BGMDevice that handles UI sounds. */
|
||||
|
|
|
@ -133,8 +133,8 @@
|
|||
// backwards compatability.
|
||||
|
||||
NSString* __nullable bundleID =
|
||||
(__bridge_transfer NSString* __nullable)[audioDevices bgmDevice].GetPropertyData_CFString(kBGMMusicPlayerBundleIDAddress);
|
||||
|
||||
(__bridge_transfer NSString* __nullable)[audioDevices bgmDevice].GetMusicPlayerBundleID();
|
||||
|
||||
DebugMsg("BGMMusicPlayers::initSelectedMusicPlayerFromBGMDevice: "
|
||||
"Trying to set selected music player by bundle ID (from BGMDriver). bundleID=%s",
|
||||
(bundleID ? bundleID.UTF8String : "(null)"));
|
||||
|
@ -224,13 +224,11 @@
|
|||
@"BGMMusicPlayers::updateBGMDeviceMusicPlayerProperties: Music player has neither bundle ID nor PID");
|
||||
|
||||
if (self.selectedMusicPlayer.pid) {
|
||||
[audioDevices bgmDevice].SetPropertyData_CFType(kBGMMusicPlayerProcessIDAddress,
|
||||
(__bridge CFNumberRef)self.selectedMusicPlayer.pid);
|
||||
[audioDevices bgmDevice].SetMusicPlayerProcessID((__bridge CFNumberRef)self.selectedMusicPlayer.pid);
|
||||
}
|
||||
|
||||
if (self.selectedMusicPlayer.bundleID) {
|
||||
[audioDevices bgmDevice].SetPropertyData_CFString(kBGMMusicPlayerBundleIDAddress,
|
||||
(__bridge CFStringRef)self.selectedMusicPlayer.bundleID);
|
||||
[audioDevices bgmDevice].SetMusicPlayerBundleID((__bridge CFStringRef)self.selectedMusicPlayer.bundleID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -174,8 +174,7 @@
|
|||
// When it doesn't find a selected music player in user defaults, it should check BGMDevice's music
|
||||
// player properties.
|
||||
|
||||
[devices bgmDevice].SetPropertyData_CFString(kBGMMusicPlayerBundleIDAddress,
|
||||
CFSTR("org.videolan.vlc"));
|
||||
[devices bgmDevice].SetMusicPlayerBundleID(CFSTR("org.videolan.vlc"));
|
||||
|
||||
BGMMusicPlayers* players = [[BGMMusicPlayers alloc] initWithAudioDevices:devices
|
||||
userDefaults:defaults];
|
||||
|
@ -190,7 +189,7 @@
|
|||
|
||||
- (void) resetDevice {
|
||||
// Reset the mock BGMDevice.
|
||||
[devices bgmDevice].SetPropertyData_CFString(kBGMMusicPlayerBundleIDAddress, NULL);
|
||||
[devices bgmDevice].SetMusicPlayerBundleID(CFSTR(""));
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -32,9 +32,9 @@
|
|||
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
// The value of the music player bundle ID property. Tests should set this back to NULL when they finish. (Has
|
||||
// The value of the music player bundle ID property. Tests should set this back to "" when they finish. (Has
|
||||
// to be static because we can't add to the real class's interface.)
|
||||
static CFStringRef __nullable playerBundleID = NULL;
|
||||
static CFStringRef playerBundleID = CFSTR("");
|
||||
|
||||
CAHALAudioObject::CAHALAudioObject(AudioObjectID inObjectID)
|
||||
:
|
||||
|
|
|
@ -946,7 +946,7 @@ void BGM_Device::Device_GetPropertyData(AudioObjectID inObjectID, pid_t inClient
|
|||
ThrowIf(inDataSize < sizeof(CFNumberRef), CAException(kAudioHardwareBadPropertySizeError), "BGM_Device::Device_GetPropertyData: not enough space for the return value of kAudioDeviceCustomPropertyMusicPlayerProcessID for the device");
|
||||
CAMutex::Locker theStateLocker(mStateMutex);
|
||||
pid_t pid = mClients.GetMusicPlayerProcessIDProperty();
|
||||
*reinterpret_cast<CFNumberRef*>(outData) = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pid);
|
||||
*reinterpret_cast<CFNumberRef*>(outData) = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid);
|
||||
outDataSize = sizeof(CFNumberRef);
|
||||
}
|
||||
break;
|
||||
|
@ -1022,7 +1022,7 @@ void BGM_Device::Device_SetPropertyData(AudioObjectID inObjectID, pid_t inClient
|
|||
// pid variable, and we want that to be an error.)
|
||||
pid_t pid = INT_MIN;
|
||||
// CFNumberGetValue docs: "If the conversion is lossy, or the value is out of range, false is returned."
|
||||
Boolean success = CFNumberGetValue(pidRef, kCFNumberSInt32Type, &pid);
|
||||
Boolean success = CFNumberGetValue(pidRef, kCFNumberIntType, &pid);
|
||||
|
||||
ThrowIf(!success, CAException(kAudioHardwareIllegalOperationError), "BGM_Device::Device_SetPropertyData: probable error from CFNumberGetValue when reading pid for kAudioDeviceCustomPropertyMusicPlayerProcessID");
|
||||
|
||||
|
|
Loading…
Reference in a new issue