mirror of
https://github.com/kyleneideck/BackgroundMusic
synced 2024-11-26 14:10:16 +00:00
Add packaging script and (possibly) support for OS X 10.9.
This commit is contained in:
parent
8d1adf25bb
commit
5e4556b49d
17 changed files with 656 additions and 187 deletions
|
@ -62,6 +62,15 @@ script:
|
|||
- if ls -la "/usr/local/libexec/BGMXPCHelper.xpc"; then false; fi
|
||||
- if ls -la "/Library/Application Support/Background Music/BGMXPCHelper.xpc"; then false; fi
|
||||
- if ls -la "/Library/LaunchDaemons/com.bearisdriving.BGM.XPCHelper.plist"; then false; fi
|
||||
# Build the .pkg installer.
|
||||
- ./package.sh
|
||||
# Install the .pkg.
|
||||
- sudo installer -pkg Background-Music-*/BackgroundMusic-*.pkg -target / -verbose -dumplog
|
||||
# Check the BGM dirs and files were installed again.
|
||||
- ls -la "/Applications/Background Music.app"
|
||||
- ls -la "/Library/Audio/Plug-Ins/HAL/Background Music Device.driver"
|
||||
- ls -la "/usr/local/libexec/BGMXPCHelper.xpc" || ls -la "/Library/Application Support/Background Music/BGMXPCHelper.xpc"
|
||||
- ls -la "/Library/LaunchDaemons/com.bearisdriving.BGM.XPCHelper.plist"
|
||||
# Post on IRC when Travis builds finish.
|
||||
notifications:
|
||||
irc: "irc.freenode.org#backgroundmusic"
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
1C4699471BD5C0E400F78043 /* BGMiTunes.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C4699461BD5C0E400F78043 /* BGMiTunes.m */; };
|
||||
1C46994E1BD7694C00F78043 /* BGMDeviceControlSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C46994C1BD7694C00F78043 /* BGMDeviceControlSync.cpp */; };
|
||||
1C50FF631EC9F4490031A6EA /* BGMAudioDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CF5423A1EAAEE4300445AD8 /* BGMAudioDevice.cpp */; };
|
||||
1C533C7A1EED28B700270802 /* uninstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 1C533C791EED28B700270802 /* uninstall.sh */; };
|
||||
1C533C7B1EED2F6200270802 /* safe_install_dir.sh in Resources */ = {isa = PBXBuildFile; fileRef = 276972901CB16008007A2F7C /* safe_install_dir.sh */; };
|
||||
1C533C7C1EED2F8A00270802 /* com.bearisdriving.BGM.XPCHelper.plist.template in Resources */ = {isa = PBXBuildFile; fileRef = 2769728D1CAFCEFD007A2F7C /* com.bearisdriving.BGM.XPCHelper.plist.template */; };
|
||||
1CB8B33D1BBA75EF000E2DD1 /* BGMAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CB8B33C1BBA75EF000E2DD1 /* BGMAppDelegate.mm */; };
|
||||
1CB8B33F1BBA75EF000E2DD1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1CB8B33E1BBA75EF000E2DD1 /* main.m */; };
|
||||
1CC1DF811BE5068A00FB8FE4 /* CACFArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CC1DF7D1BE5068A00FB8FE4 /* CACFArray.cpp */; };
|
||||
|
@ -127,8 +130,6 @@
|
|||
2743CA221D86DE960089613B /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C1963021BCAC160008A4DF7 /* CoreAudio.framework */; };
|
||||
2743CA231D86DEA70089613B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CD1FD2F1BDDEAF2004F7E1B /* AudioToolbox.framework */; };
|
||||
274827951E11052500B31D8D /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1CB8B3421BBA75EF000E2DD1 /* MainMenu.xib */; };
|
||||
2769728F1CAFF22C007A2F7C /* com.bearisdriving.BGM.XPCHelper.plist.template in Resources */ = {isa = PBXBuildFile; fileRef = 2769728D1CAFCEFD007A2F7C /* com.bearisdriving.BGM.XPCHelper.plist.template */; };
|
||||
276972921CB1603E007A2F7C /* safe_install_dir.sh in Resources */ = {isa = PBXBuildFile; fileRef = 276972901CB16008007A2F7C /* safe_install_dir.sh */; };
|
||||
277170161CA24D7C00AB34B4 /* BGMXPCListenerDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 277170151CA24D7C00AB34B4 /* BGMXPCListenerDelegate.m */; };
|
||||
2795973B1C982E4E00A002FB /* BGMXPCListener.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2795973A1C982E4E00A002FB /* BGMXPCListener.mm */; };
|
||||
279F48771DD6D73A00768A85 /* BGMHermes.m in Sources */ = {isa = PBXBuildFile; fileRef = 279F48761DD6D73900768A85 /* BGMHermes.m */; };
|
||||
|
@ -214,6 +215,7 @@
|
|||
1C46994C1BD7694C00F78043 /* BGMDeviceControlSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BGMDeviceControlSync.cpp; sourceTree = "<group>"; };
|
||||
1C46994D1BD7694C00F78043 /* BGMDeviceControlSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BGMDeviceControlSync.h; sourceTree = "<group>"; };
|
||||
1C50FF641EC9F4500031A6EA /* libPublicUtility.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPublicUtility.a; path = "../../../Library/Developer/Xcode/DerivedData/BGM-cgeucfvbrkmtbnhewbqjwrqspirp/Build/Products/Debug/libPublicUtility.a"; sourceTree = "<group>"; };
|
||||
1C533C791EED28B700270802 /* uninstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = uninstall.sh; path = ../../uninstall.sh; sourceTree = "<group>"; };
|
||||
1C8034C21BDAFD5700668E00 /* CAPThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAPThread.cpp; path = PublicUtility/CAPThread.cpp; sourceTree = "<group>"; };
|
||||
1C8034C31BDAFD5700668E00 /* CAPThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAPThread.h; path = PublicUtility/CAPThread.h; sourceTree = "<group>"; };
|
||||
1CB8B3361BBA75EF000E2DD1 /* Background Music.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Background Music.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -518,6 +520,7 @@
|
|||
1CED61681C3081C2002CAFCF /* LICENSE */,
|
||||
1CC1DF951BE8607700FB8FE4 /* Images.xcassets */,
|
||||
1CB8B33A1BBA75EF000E2DD1 /* Info.plist */,
|
||||
1C533C791EED28B700270802 /* uninstall.sh */,
|
||||
1CB8B33E1BBA75EF000E2DD1 /* main.m */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
|
@ -795,6 +798,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
274827951E11052500B31D8D /* MainMenu.xib in Resources */,
|
||||
1C533C7A1EED28B700270802 /* uninstall.sh in Resources */,
|
||||
1CED61691C3081C2002CAFCF /* LICENSE in Resources */,
|
||||
1C2FC3041EB4D6E700A76592 /* BGMApp.sdef in Resources */,
|
||||
1CC1DF961BE8607700FB8FE4 /* Images.xcassets in Resources */,
|
||||
|
@ -812,8 +816,8 @@
|
|||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
276972921CB1603E007A2F7C /* safe_install_dir.sh in Resources */,
|
||||
2769728F1CAFF22C007A2F7C /* com.bearisdriving.BGM.XPCHelper.plist.template in Resources */,
|
||||
1C533C7C1EED2F8A00270802 /* com.bearisdriving.BGM.XPCHelper.plist.template in Resources */,
|
||||
1C533C7B1EED2F6200270802 /* safe_install_dir.sh in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1114,7 +1118,7 @@
|
|||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
|
@ -1210,7 +1214,7 @@
|
|||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
|
@ -1284,7 +1288,7 @@
|
|||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
SDKROOT = macosx;
|
||||
|
|
|
@ -65,21 +65,57 @@ static float const kStatusBarIconPadding = 0.25;
|
|||
|
||||
haveShownXPCHelperErrorMessage = NO;
|
||||
|
||||
// Set up the status bar item
|
||||
[self initStatusBarItem];
|
||||
}
|
||||
|
||||
// Set up the status bar item. (The thing you click to show BGMApp's UI.)
|
||||
- (void) initStatusBarItem {
|
||||
statusBarItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
|
||||
|
||||
// Set the icon
|
||||
NSImage* icon = [NSImage imageNamed:@"FermataIcon"];
|
||||
|
||||
// NSStatusItem doesn't have the "button" property on OS X 10.9.
|
||||
BOOL buttonAvailable = (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_10);
|
||||
|
||||
if (icon != nil) {
|
||||
CGFloat lengthMinusPadding = [[statusBarItem button] frame].size.height * (1 - kStatusBarIconPadding);
|
||||
NSRect statusBarItemFrame;
|
||||
|
||||
if (buttonAvailable) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
statusBarItemFrame = statusBarItem.button.frame;
|
||||
#pragma clang diagnostic pop
|
||||
} else {
|
||||
// OS X 10.9 fallback. I haven't tested this (or anything else on 10.9).
|
||||
statusBarItemFrame = statusBarItem.view.frame;
|
||||
}
|
||||
|
||||
CGFloat lengthMinusPadding = statusBarItemFrame.size.height * (1 - kStatusBarIconPadding);
|
||||
[icon setSize:NSMakeSize(lengthMinusPadding, lengthMinusPadding)];
|
||||
|
||||
// Make the icon a "template image" so it gets drawn colour-inverted when it's highlighted or the status
|
||||
// bar's in dark mode
|
||||
[icon setTemplate:YES];
|
||||
statusBarItem.button.image = icon;
|
||||
|
||||
if (buttonAvailable) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
statusBarItem.button.image = icon;
|
||||
#pragma clang diagnostic pop
|
||||
} else {
|
||||
statusBarItem.image = icon;
|
||||
}
|
||||
} else {
|
||||
// If our icon is missing for some reason, fallback to a fermata character (1D110)
|
||||
statusBarItem.button.title = @"𝄐";
|
||||
if (buttonAvailable) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
statusBarItem.button.title = @"𝄐";
|
||||
#pragma clang diagnostic pop
|
||||
} else {
|
||||
statusBarItem.title = @"𝄐";
|
||||
}
|
||||
}
|
||||
|
||||
// Set the main menu
|
||||
|
|
|
@ -124,9 +124,12 @@ static CGFloat const kAppVolumeViewInitialHeight = 20;
|
|||
|
||||
// NSMenuItem didn't implement NSAccessibility before OS X SDK 10.12.
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 // MAC_OS_X_VERSION_10_12
|
||||
if ([self respondsToSelector:@selector(accessibilityTitle)]) {
|
||||
if ([appVolItem respondsToSelector:@selector(setAccessibilityTitle:)]) {
|
||||
// TODO: This doesn't show up in Accessibility Inspector for me. Not sure why.
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
appVolItem.accessibilityTitle = [NSString stringWithFormat:@"%@", [app localizedName]];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -365,7 +368,12 @@ static CGFloat const kAppVolumeViewInitialHeight = 20;
|
|||
// when they have non-default values.
|
||||
[ctx showHideExtraControls:self];
|
||||
|
||||
self.accessibilityTitle = @"More options";
|
||||
if ([self respondsToSelector:@selector(setAccessibilityTitle:)]) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
self.accessibilityTitle = @"More options";
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -391,7 +399,12 @@ static CGFloat const kAppVolumeViewInitialHeight = 20;
|
|||
self.maxValue = kAppRelativeVolumeMaxRawValue;
|
||||
self.minValue = kAppRelativeVolumeMinRawValue;
|
||||
|
||||
self.accessibilityTitle = [NSString stringWithFormat:@"Volume for %@", [app localizedName]];
|
||||
if ([self respondsToSelector:@selector(setAccessibilityTitle:)]) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
self.accessibilityTitle = [NSString stringWithFormat:@"Volume for %@", [app localizedName]];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
// We have to handle snapping for volume sliders ourselves because adding a tick mark (snap point) in Interface Builder
|
||||
|
@ -442,7 +455,12 @@ static CGFloat const kAppVolumeViewInitialHeight = 20;
|
|||
self.minValue = kAppPanLeftRawValue;
|
||||
self.maxValue = kAppPanRightRawValue;
|
||||
|
||||
self.accessibilityTitle = [NSString stringWithFormat:@"Pan for %@", [app localizedName]];
|
||||
if ([self respondsToSelector:@selector(setAccessibilityTitle:)]) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
self.accessibilityTitle = [NSString stringWithFormat:@"Pan for %@", [app localizedName]];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setPanPosition:(NSNumber *)panPosition {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
// BGMAutoPauseMusic.m
|
||||
// BGMApp
|
||||
//
|
||||
// Copyright © 2016 Kyle Neideck
|
||||
// Copyright © 2016, 2017 Kyle Neideck
|
||||
//
|
||||
|
||||
// Self Include
|
||||
|
@ -84,7 +84,18 @@ static Float32 const kUnpauseDelayWeightingFactor = 0.25f;
|
|||
enabled = NO;
|
||||
wePaused = NO;
|
||||
|
||||
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0);
|
||||
dispatch_queue_attr_t attr;
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
if (&dispatch_queue_attr_make_with_qos_class) {
|
||||
attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0);
|
||||
} else {
|
||||
// OS X 10.9 fallback
|
||||
attr = DISPATCH_QUEUE_SERIAL;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
listenerQueue = dispatch_queue_create("com.bearisdriving.BGM.AutoPauseMusic.Listener", attr);
|
||||
pauseUnpauseMusicQueue = dispatch_queue_create("com.bearisdriving.BGM.AutoPauseMusic.PauseUnpauseMusic", attr);
|
||||
|
||||
|
|
|
@ -50,12 +50,25 @@ BGMDeviceControlsList::BGMDeviceControlsList(AudioObjectID inBGMDevice,
|
|||
BGMAssert((mBGMDevice.GetObjectID() == mAudioSystem.GetAudioDeviceForUID(CFSTR(kBGMDeviceUID)) ||
|
||||
mBGMDevice.GetObjectID() == kAudioObjectUnknown),
|
||||
"BGMDeviceControlsList::BGMDeviceControlsList: Given device is not BGMDevice");
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
mCanToggleDeviceOnSystem = (&dispatch_block_wait &&
|
||||
&dispatch_block_cancel &&
|
||||
&dispatch_block_testcancel &&
|
||||
&dispatch_queue_attr_make_with_qos_class);
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
BGMDeviceControlsList::~BGMDeviceControlsList()
|
||||
{
|
||||
CAMutex::Locker locker(mMutex);
|
||||
|
||||
if(!mDeviceTogglingInitialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BGMLogAndSwallowExceptions("BGMDeviceControlsList::~BGMDeviceControlsList", [&] {
|
||||
mAudioSystem.RemovePropertyListenerBlock(CAPropertyAddress(kAudioHardwarePropertyDevices),
|
||||
mListenerQueue,
|
||||
|
@ -75,7 +88,10 @@ BGMDeviceControlsList::~BGMDeviceControlsList()
|
|||
// Note that if mDisableNullDeviceBlock is currently running this will return after it
|
||||
// finishes and if it's already run this will return immediately. So we don't have to
|
||||
// worry about ending up waiting for mDisableNullDeviceBlock when it isn't queued.
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
bool timedOut = dispatch_block_wait(disableNullDeviceBlock, kDisableNullDeviceTimeout);
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
if(timedOut)
|
||||
{
|
||||
|
@ -111,10 +127,9 @@ bool BGMDeviceControlsList::MatchControlsListOf(AudioObjectID inDeviceID)
|
|||
{
|
||||
CAMutex::Locker locker(mMutex);
|
||||
|
||||
LazyInit();
|
||||
|
||||
if(mBGMDevice == kAudioObjectUnknown)
|
||||
if(mBGMDevice.GetObjectID() != mAudioSystem.GetAudioDeviceForUID(CFSTR(kBGMDeviceUID)))
|
||||
{
|
||||
LogWarning("BGMDeviceControlsList::MatchControlsListOf: BGMDevice ID not set");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -228,13 +243,13 @@ void BGMDeviceControlsList::PropagateControlListChange()
|
|||
{
|
||||
CAMutex::Locker locker(mMutex);
|
||||
|
||||
LazyInit();
|
||||
|
||||
if(mBGMDevice == kAudioObjectUnknown)
|
||||
if((mBGMDevice == kAudioObjectUnknown) || !mCanToggleDeviceOnSystem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InitDeviceToggling();
|
||||
|
||||
// Leave the default device alone if the user has changed it since launching BGMApp.
|
||||
bool bgmDeviceIsDefault = true;
|
||||
|
||||
|
@ -267,17 +282,18 @@ void BGMDeviceControlsList::PropagateControlListChange()
|
|||
|
||||
#pragma mark Implementation
|
||||
|
||||
void BGMDeviceControlsList::LazyInit()
|
||||
void BGMDeviceControlsList::InitDeviceToggling()
|
||||
{
|
||||
CAMutex::Locker locker(mMutex);
|
||||
|
||||
if(mInitialised)
|
||||
if(mDeviceTogglingInitialised || !mCanToggleDeviceOnSystem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BGMAssert(mBGMDevice.GetObjectID() == mAudioSystem.GetAudioDeviceForUID(CFSTR(kBGMDeviceUID)),
|
||||
"BGMDeviceControlsList::LazyInit: mBGMDevice device is not set to BGMDevice's ID");
|
||||
"BGMDeviceControlsList::InitDeviceToggling: mBGMDevice device is not set to "
|
||||
"BGMDevice's ID");
|
||||
|
||||
mDeviceToggleBlock = CreateDeviceToggleBlock();
|
||||
mDeviceToggleBackBlock = CreateDeviceToggleBackBlock();
|
||||
|
@ -285,8 +301,11 @@ void BGMDeviceControlsList::LazyInit()
|
|||
|
||||
// Register a listener to find out when the Null Device becomes available/unavailable. See
|
||||
// ToggleDefaultDevice.
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
dispatch_queue_attr_t attr =
|
||||
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0);
|
||||
#pragma clang diagnostic pop
|
||||
mListenerQueue = dispatch_queue_create("com.bearisdriving.BGM.BGMDeviceControlsList", attr);
|
||||
|
||||
mListenerBlock = ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress* inAddresses) {
|
||||
|
@ -302,35 +321,35 @@ void BGMDeviceControlsList::LazyInit()
|
|||
switch(inAddresses[i].mSelector)
|
||||
{
|
||||
case kAudioHardwarePropertyDevices:
|
||||
{
|
||||
CAMutex::Locker innerLocker(mMutex);
|
||||
{
|
||||
CAMutex::Locker innerLocker(mMutex);
|
||||
|
||||
DebugMsg("BGMDeviceControlsList::LazyInit: Got "
|
||||
"kAudioHardwarePropertyDevices");
|
||||
DebugMsg("BGMDeviceControlsList::InitDeviceToggling: Got "
|
||||
"kAudioHardwarePropertyDevices");
|
||||
|
||||
// Cancel the previous block in case it hasn't run yet.
|
||||
DestroyBlock(mDeviceToggleBlock);
|
||||
// Cancel the previous block in case it hasn't run yet.
|
||||
DestroyBlock(mDeviceToggleBlock);
|
||||
|
||||
mDeviceToggleBlock = CreateDeviceToggleBlock();
|
||||
mDeviceToggleBlock = CreateDeviceToggleBlock();
|
||||
|
||||
// Changing the default device too quickly after enabling the Null Device
|
||||
// seems to cause problems with some programs. Not sure why.
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, kToggleDeviceInitialDelay),
|
||||
dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0),
|
||||
mDeviceToggleBlock);
|
||||
}
|
||||
// Changing the default device too quickly after enabling the Null Device
|
||||
// seems to cause problems with some programs. Not sure why.
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, kToggleDeviceInitialDelay),
|
||||
dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0),
|
||||
mDeviceToggleBlock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BGMLogAndSwallowExceptions("BGMDeviceControlsList::LazyInit", [&] {
|
||||
BGMLogAndSwallowExceptions("BGMDeviceControlsList::InitDeviceToggling", [&] {
|
||||
mAudioSystem.AddPropertyListenerBlock(CAPropertyAddress(kAudioHardwarePropertyDevices),
|
||||
mListenerQueue,
|
||||
mListenerBlock);
|
||||
});
|
||||
|
||||
mInitialised = true;
|
||||
mDeviceTogglingInitialised = true;
|
||||
}
|
||||
|
||||
void BGMDeviceControlsList::ToggleDefaultDevice()
|
||||
|
@ -386,6 +405,9 @@ void BGMDeviceControlsList::SetNullDeviceEnabled(bool inEnabled)
|
|||
(inEnabled ? kCFBooleanTrue : kCFBooleanFalse));
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
|
||||
dispatch_block_t BGMDeviceControlsList::CreateDeviceToggleBlock()
|
||||
{
|
||||
return dispatch_block_create((dispatch_block_flags_t)0, ^{
|
||||
|
@ -479,5 +501,7 @@ void BGMDeviceControlsList::DestroyBlock(dispatch_block_t __nullable & block)
|
|||
}
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop /* -Wpartial-availability */
|
||||
|
||||
#pragma clang assume_nonnull end
|
||||
|
||||
|
|
|
@ -88,8 +88,8 @@ public:
|
|||
#pragma mark Implementation
|
||||
|
||||
private:
|
||||
/* This class is lazily initialised, mainly as a convenience for the unit tests. */
|
||||
void LazyInit();
|
||||
/*! Lazily initialises the fields used to toggle the default device. */
|
||||
void InitDeviceToggling();
|
||||
/*! Changes the OS X default audio device to the Null Device and then back to BGMDevice. */
|
||||
void ToggleDefaultDevice();
|
||||
/*!
|
||||
|
@ -109,7 +109,9 @@ private:
|
|||
|
||||
private:
|
||||
CAMutex mMutex { "Device Controls List" };
|
||||
bool mInitialised = false;
|
||||
bool mDeviceTogglingInitialised = false;
|
||||
// OS X 10.9 doesn't have the functions we use for PropagateControlListChange.
|
||||
bool mCanToggleDeviceOnSystem;
|
||||
|
||||
BGMAudioDevice mBGMDevice;
|
||||
CAHALAudioSystemObject mAudioSystem; // Not guarded by the mutex.
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
# post_install.sh
|
||||
# BGMXPCHelper
|
||||
#
|
||||
# Copyright © 2016 Kyle Neideck
|
||||
# Copyright © 2016, 2017 Kyle Neideck
|
||||
#
|
||||
# Installs BGMXPCHelper's launchd plist file and "bootstraps" (registers/enables) it with launchd.
|
||||
#
|
||||
|
@ -28,30 +28,47 @@
|
|||
# runs as the final build phase.
|
||||
#
|
||||
|
||||
# Check the environment variables we need from Xcode.
|
||||
if [[ -z ${EXECUTABLE_PATH} ]]; then
|
||||
echo "Environment variable EXECUTABLE_PATH was not set." >&2
|
||||
exit 1
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin; export PATH
|
||||
|
||||
# Check we have the paths we need, either in environment variables from Xcode or from the args.
|
||||
if [[ -z $1 ]]; then
|
||||
if [[ -z ${INSTALL_DIR} ]]; then
|
||||
echo "Environment variable INSTALL_DIR was not set." >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
INSTALL_DIR="$1"
|
||||
fi
|
||||
if [[ -z ${INSTALL_DIR} ]]; then
|
||||
echo "Environment variable INSTALL_DIR was not set." >&2
|
||||
exit 1
|
||||
|
||||
if [[ -z $2 ]]; then
|
||||
if [[ -z ${EXECUTABLE_PATH} ]]; then
|
||||
echo "Environment variable EXECUTABLE_PATH was not set." >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
EXECUTABLE_PATH="$2"
|
||||
fi
|
||||
if [[ -z ${TARGET_BUILD_DIR} ]]; then
|
||||
echo "Environment variable TARGET_BUILD_DIR was not set." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH} ]]; then
|
||||
echo "Environment variable UNLOCALIZED_RESOURCES_FOLDER_PATH was not set." >&2
|
||||
exit 1
|
||||
|
||||
if [[ -z $3 ]]; then
|
||||
if [[ -z ${TARGET_BUILD_DIR} ]]; then
|
||||
echo "Environment variable TARGET_BUILD_DIR was not set." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH} ]]; then
|
||||
echo "Environment variable UNLOCALIZED_RESOURCES_FOLDER_PATH was not set." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RESOURCES_PATH="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
else
|
||||
RESOURCES_PATH="$3"
|
||||
fi
|
||||
|
||||
# Safe mode.
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
RESOURCES_PATH="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
|
||||
# Show a warning if INSTALL_DIR isn't set to a safe installation directory.
|
||||
if [[ $(bash "${RESOURCES_PATH}/safe_install_dir.sh" "${INSTALL_DIR}") != 1 ]]; then
|
||||
echo "$(tput setaf 11)WARNING$(tput sgr0): Installing to \"${INSTALL_DIR}\" may be" \
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
# safe_install_dir.sh
|
||||
# BGMXPCHelper
|
||||
#
|
||||
# Copyright © 2016 Kyle Neideck
|
||||
# Copyright © 2016, 2017 Kyle Neideck
|
||||
#
|
||||
# Prints the path to a directory the BGMXPCHelper bundle can safely be installed to. Intended to be
|
||||
# used as the INSTALL_DIR environment variable for xcodebuild commands. For example,
|
||||
|
@ -56,6 +56,8 @@
|
|||
# recommendation above, or "0" otherwise.
|
||||
#
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin; export PATH
|
||||
|
||||
# Safe mode.
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
@ -96,13 +98,17 @@ check_dir() {
|
|||
# Used when we can't find a suitable installation directory. Prints an error message and exits.
|
||||
# (Reaching this point should be very uncommon.)
|
||||
fail() {
|
||||
echo "$(tput setaf 11)WARNING$(tput sgr0): Installing BGMXPCHelper to its default location" \
|
||||
"(${INSTALL_DIR} or, as a backup, ${BACKUP_INSTALL_DIR}) might not be secure on this" \
|
||||
"system. It's recommended that each directory from the installation directory up to the" \
|
||||
"root directory should be owned by root and not writable by any other user. See" \
|
||||
"safe_install_dir.sh for more details." >&2
|
||||
if [[ $ALLOW_UNSAFE_FALLBACK -eq 1 ]]; then
|
||||
CONTINUE_ANYWAY="y"
|
||||
else
|
||||
echo "$(tput setaf 11)WARNING$(tput sgr0): Installing BGMXPCHelper to its default" \
|
||||
"location (${INSTALL_DIR} or, as a backup, ${BACKUP_INSTALL_DIR}) might not be" \
|
||||
"secure on this system. It's recommended that each directory from the installation" \
|
||||
"directory up to the root directory should be owned by root and not writable by any" \
|
||||
"other user. See safe_install_dir.sh for more details." >&2
|
||||
|
||||
read -e -p "Continue anyway? [y/N]" CONTINUE_ANYWAY
|
||||
read -e -p "Continue anyway? [y/N]" CONTINUE_ANYWAY
|
||||
fi
|
||||
|
||||
if [[ "${CONTINUE_ANYWAY}" == "y" ]] || [[ "${CONTINUE_ANYWAY}" == "Y" ]]; then
|
||||
echo "${INSTALL_DIR}"
|
||||
|
@ -114,16 +120,26 @@ fail() {
|
|||
fi
|
||||
}
|
||||
|
||||
# This script can be given a directory to check as an argument.
|
||||
# (Uses "${1+x}" instead of "$1" because having our "safe mode" enabled makes the script fail if you
|
||||
# reference an unset variable, even to check whether it's set or not.)
|
||||
if [[ ! -z "${1+x}" ]]; then
|
||||
# Check the given path exists and is a directory.
|
||||
if [[ ! -d "$1" ]]; then echo "$1 is not a directory." >&2; exit 1; fi
|
||||
ALLOW_UNSAFE_FALLBACK=0
|
||||
|
||||
check_dir "$1"
|
||||
echo ${DIR_IS_SAFE}
|
||||
exit 0
|
||||
# This script can be given a directory to check as an argument, or the -y option, which tells this
|
||||
# script to print the default dir if neither of the dirs are safe. The pkg installer uses -y so it
|
||||
# can install anyway and show the user instructions to fix the permissions, rather than just
|
||||
# failing.
|
||||
#
|
||||
# (This line uses "${1+x}" instead of "$1" because having our "safe mode" enabled makes the script
|
||||
# fail if you reference an unset variable, even to check whether it's set or not.)
|
||||
if [[ ! -z "${1+x}" ]]; then
|
||||
if [[ "$1" == "-y" ]]; then
|
||||
ALLOW_UNSAFE_FALLBACK=1
|
||||
else
|
||||
# Check the given path exists and is a directory.
|
||||
if [[ ! -d "$1" ]]; then echo "$1 is not a directory." >&2; exit 1; fi
|
||||
|
||||
check_dir "$1"
|
||||
echo ${DIR_IS_SAFE}
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# These are just for readability and to save keystrokes. If you change them, you'll have to change
|
||||
|
@ -143,7 +159,7 @@ if [[ ! -e "${INSTALL_DIR}" ]]; then
|
|||
sudo chmod go-w "${INSTALL_DIR}"
|
||||
fi
|
||||
|
||||
# Check the directory Xcode installed the build to.
|
||||
# Check the directory the build was installed to.
|
||||
check_dir "${INSTALL_DIR}"
|
||||
|
||||
if [[ ${DIR_IS_SAFE} -eq 1 ]]; then
|
||||
|
|
|
@ -622,7 +622,7 @@
|
|||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
WARNING_CFLAGS = "-Wpartial-availability";
|
||||
|
@ -684,7 +684,7 @@
|
|||
GCC_WARN_UNUSED_LABEL = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
WARNING_CFLAGS = "-Wpartial-availability";
|
||||
};
|
||||
|
@ -714,7 +714,6 @@
|
|||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = BGMDriver/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Audio/Plug-Ins/HAL";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.bearisdriving.BGM.Driver;
|
||||
|
@ -749,7 +748,6 @@
|
|||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = BGMDriver/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Audio/Plug-Ins/HAL";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.bearisdriving.BGM.Driver;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AudioServerPlugIn_MachServices</key>
|
||||
<array>
|
||||
<string>com.bearisdriving.BGM.XPCHelper</string>
|
||||
</array>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
@ -15,11 +19,11 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>0.0.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<string>1.0.0</string>
|
||||
<key>CFPlugInFactories</key>
|
||||
<dict>
|
||||
<key>C957AD43-DACA-4A40-8850-3BA8CE28FAF9</key>
|
||||
|
@ -34,9 +38,5 @@
|
|||
</dict>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
<key>AudioServerPlugIn_MachServices</key>
|
||||
<array>
|
||||
<string>com.bearisdriving.BGM.XPCHelper</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#
|
||||
# build_and_install.sh
|
||||
#
|
||||
# Copyright © 2016 Kyle Neideck
|
||||
# Copyright © 2016, 2017 Kyle Neideck
|
||||
# Copyright © 2016 Nick Jacques
|
||||
#
|
||||
# Builds and installs BGMApp, BGMDriver and BGMXPCHelper. Requires xcodebuild and Xcode.
|
||||
|
@ -99,6 +99,8 @@ disable_error_handling() {
|
|||
CONFIGURATION=Release
|
||||
#CONFIGURATION=Debug
|
||||
|
||||
XCODEBUILD_ACTION="install"
|
||||
|
||||
# The default is to clean before installing because we want the log file to have roughly the same
|
||||
# information after every build.
|
||||
CLEAN=clean
|
||||
|
@ -154,6 +156,7 @@ usage() {
|
|||
echo "Usage: $0 [options]" >&2
|
||||
echo -e "\t-n Don't clean before building/installing." >&2
|
||||
echo -e "\t-d Debug build. (Release is the default.)" >&2
|
||||
echo -e "\t-b Build only, don't install." >&2
|
||||
echo -e "\t-w Ignore compiler warnings. (They're treated as errors by default.)" >&2
|
||||
echo -e "\t-x [options] Extra options to pass to xcodebuild." >&2
|
||||
echo -e "\t-c Continue on script errors. Might not be safe." >&2
|
||||
|
@ -236,7 +239,7 @@ show_spinner() {
|
|||
}
|
||||
|
||||
parse_options() {
|
||||
while getopts ":ndwx:ch" opt; do
|
||||
while getopts ":ndbwx:ch" opt; do
|
||||
case $opt in
|
||||
n)
|
||||
CLEAN=""
|
||||
|
@ -244,6 +247,13 @@ parse_options() {
|
|||
d)
|
||||
CONFIGURATION="Debug"
|
||||
;;
|
||||
b)
|
||||
XCODEBUILD_ACTION="build"
|
||||
# The dirs xcodebuild will build in.
|
||||
APP_PATH="./BGMApp/build"
|
||||
DRIVER_PATH="./BGMDriver/build"
|
||||
XPC_HELPER_PATH="${APP_PATH}"
|
||||
;;
|
||||
w)
|
||||
# TODO: What if they also pass their own OTHER_CFLAGS with -x?
|
||||
XCODEBUILD_OPTIONS="${XCODEBUILD_OPTIONS} OTHER_CFLAGS=\"-Wno-error\""
|
||||
|
@ -529,15 +539,20 @@ if [[ $(id -u) -eq 0 ]]; then
|
|||
fi
|
||||
|
||||
# Print initial message.
|
||||
echo "$(bold_face About to install Background Music). Please pause all audio, if you can."
|
||||
[[ "${CONFIGURATION}" == "Debug" ]] && echo "Debug build."
|
||||
echo
|
||||
echo "This script will install:"
|
||||
echo " - ${APP_PATH}/${APP_DIR}"
|
||||
echo " - ${DRIVER_PATH}/${DRIVER_DIR}"
|
||||
echo " - ${XPC_HELPER_PATH}/${XPC_HELPER_DIR}"
|
||||
echo " - /Library/LaunchDaemons/com.bearisdriving.BGM.XPCHelper.plist"
|
||||
echo
|
||||
if [[ "${XCODEBUILD_ACTION}" == "install" ]]; then
|
||||
echo "$(bold_face About to install Background Music). Please pause all audio, if you can."
|
||||
[[ "${CONFIGURATION}" == "Debug" ]] && echo "Debug build."
|
||||
echo
|
||||
echo "This script will install:"
|
||||
echo " - ${APP_PATH}/${APP_DIR}"
|
||||
echo " - ${DRIVER_PATH}/${DRIVER_DIR}"
|
||||
echo " - ${XPC_HELPER_PATH}/${XPC_HELPER_DIR}"
|
||||
echo " - /Library/LaunchDaemons/com.bearisdriving.BGM.XPCHelper.plist"
|
||||
echo
|
||||
elif [[ "${XCODEBUILD_ACTION}" == "build" ]]; then
|
||||
echo "$(bold_face Building Background Music...)"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Make sure Xcode and the command line tools are installed and recent enough.
|
||||
# This sets XCODE_VERSION to major.minor, e.g. 8.3, or -1 if Xcode isn't installed.
|
||||
|
@ -545,11 +560,13 @@ XCODE_VERSION=$((${XCODEBUILD} -version 2>/dev/null || echo 'V -1') | head -n 1
|
|||
check_xcode &
|
||||
CHECK_XCODE_TASK_PID=$!
|
||||
|
||||
read -p "Continue (y/N)? " CONTINUE_INSTALLATION
|
||||
if [[ "${XCODEBUILD_ACTION}" == "install" ]]; then
|
||||
read -p "Continue (y/N)? " CONTINUE_INSTALLATION
|
||||
|
||||
if [[ "${CONTINUE_INSTALLATION}" != "y" ]] && [[ "${CONTINUE_INSTALLATION}" != "Y" ]]; then
|
||||
echo "Installation cancelled."
|
||||
exit 0
|
||||
if [[ "${CONTINUE_INSTALLATION}" != "y" ]] && [[ "${CONTINUE_INSTALLATION}" != "Y" ]]; then
|
||||
echo "Installation cancelled."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# If the check_xcode process has already finished, we can check the result early.
|
||||
|
@ -563,14 +580,16 @@ if ! is_alive ${CHECK_XCODE_TASK_PID}; then
|
|||
enable_error_handling
|
||||
fi
|
||||
|
||||
# Update the user's sudo timestamp. (Prompts the user for their password.)
|
||||
# Don't call sudo -v if this is a Travis CI build.
|
||||
if ([[ -z ${TRAVIS:-} ]] || [[ "${TRAVIS}" != true ]]) && ! sudo -v; then
|
||||
echo "$(tput setaf 9)ERROR$(tput sgr0): This script must be run by a user with administrator" \
|
||||
"(sudo) privileges." >&2
|
||||
exit 1
|
||||
if [[ "${XCODEBUILD_ACTION}" == "install" ]]; then
|
||||
# Update the user's sudo timestamp. (Prompts the user for their password.)
|
||||
# Don't call sudo -v if this is a Travis CI build.
|
||||
if ([[ -z ${TRAVIS:-} ]] || [[ "${TRAVIS}" != true ]]) && ! sudo -v; then
|
||||
echo "$(tput setaf 9)ERROR$(tput sgr0): This script must be run by a user with" \
|
||||
"administrator (sudo) privileges." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo
|
||||
fi
|
||||
echo
|
||||
|
||||
while [[ ${NEED_TO_HANDLE_CHECK_XCODE_RESULT} -ne 0 ]]; do
|
||||
disable_error_handling
|
||||
|
@ -585,119 +604,127 @@ log_debug_info $*
|
|||
|
||||
# BGMDriver
|
||||
|
||||
echo "[1/3] Installing the virtual audio device $(bold_face ${DRIVER_DIR}) to" \
|
||||
"$(bold_face ${DRIVER_PATH})." \
|
||||
if [[ "${XCODEBUILD_ACTION}" == "install" ]]; then
|
||||
SUDO="sudo"
|
||||
ACTIONING="Installing"
|
||||
else
|
||||
SUDO=""
|
||||
ACTIONING="Building"
|
||||
fi
|
||||
|
||||
echo "[1/3] ${ACTIONING} the virtual audio device $(bold_face ${DRIVER_DIR}) to" \
|
||||
"$(bold_face ${DRIVER_PATH})" \
|
||||
| tee -a ${LOG_FILE}
|
||||
|
||||
# Disable the -e shell option and error trap for build commands so we can handle errors differently.
|
||||
(disable_error_handling
|
||||
# Build Apple's PublicUtility classes as a static library.
|
||||
sudo "${XCODEBUILD}" -project BGMDriver/BGMDriver.xcodeproj \
|
||||
-target "PublicUtility" \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
${XCODEBUILD_OPTIONS} \
|
||||
${CLEAN} build >> ${LOG_FILE} 2>&1) &
|
||||
${SUDO} "${XCODEBUILD}" -project BGMDriver/BGMDriver.xcodeproj \
|
||||
-target "PublicUtility" \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
${XCODEBUILD_OPTIONS} \
|
||||
${CLEAN} build >> ${LOG_FILE} 2>&1) &
|
||||
|
||||
(disable_error_handling
|
||||
# Build and install BGMDriver
|
||||
# TODO: Should these use -scheme instead?
|
||||
sudo "${XCODEBUILD}" -project BGMDriver/BGMDriver.xcodeproj \
|
||||
-target "Background Music Device" \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
DSTROOT="/" \
|
||||
${XCODEBUILD_OPTIONS} \
|
||||
${CLEAN} install >> ${LOG_FILE} 2>&1) &
|
||||
${SUDO} "${XCODEBUILD}" -project BGMDriver/BGMDriver.xcodeproj \
|
||||
-target "Background Music Device" \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
DSTROOT="/" \
|
||||
${XCODEBUILD_OPTIONS} \
|
||||
${CLEAN} "${XCODEBUILD_ACTION}" >> ${LOG_FILE} 2>&1) &
|
||||
|
||||
show_spinner "${BUILD_FAILED_ERROR_MSG}"
|
||||
|
||||
# BGMXPCHelper
|
||||
|
||||
echo "[2/3] Installing $(bold_face ${XPC_HELPER_DIR}) to $(bold_face ${XPC_HELPER_PATH})." \
|
||||
echo "[2/3] ${ACTIONING} $(bold_face ${XPC_HELPER_DIR}) to $(bold_face ${XPC_HELPER_PATH})" \
|
||||
| tee -a ${LOG_FILE}
|
||||
|
||||
(disable_error_handling
|
||||
sudo "${XCODEBUILD}" -project BGMApp/BGMApp.xcodeproj \
|
||||
-target BGMXPCHelper \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
DSTROOT="/" \
|
||||
INSTALL_PATH="${XPC_HELPER_PATH}" \
|
||||
${XCODEBUILD_OPTIONS} \
|
||||
${CLEAN} install >> ${LOG_FILE} 2>&1) &
|
||||
${SUDO} "${XCODEBUILD}" -project BGMApp/BGMApp.xcodeproj \
|
||||
-target BGMXPCHelper \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
DSTROOT="/" \
|
||||
INSTALL_PATH="${XPC_HELPER_PATH}" \
|
||||
${XCODEBUILD_OPTIONS} \
|
||||
${CLEAN} "${XCODEBUILD_ACTION}" >> ${LOG_FILE} 2>&1) &
|
||||
|
||||
show_spinner "${BUILD_FAILED_ERROR_MSG}"
|
||||
|
||||
# BGMApp
|
||||
|
||||
echo "[3/3] Installing $(bold_face ${APP_DIR}) to $(bold_face ${APP_PATH})." \
|
||||
echo "[3/3] ${ACTIONING} $(bold_face ${APP_DIR}) to $(bold_face ${APP_PATH})" \
|
||||
| tee -a ${LOG_FILE}
|
||||
|
||||
(disable_error_handling
|
||||
sudo "${XCODEBUILD}" -project BGMApp/BGMApp.xcodeproj \
|
||||
-target "Background Music" \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
DSTROOT="/" \
|
||||
${XCODEBUILD_OPTIONS} \
|
||||
${CLEAN} install >> ${LOG_FILE} 2>&1) &
|
||||
${SUDO} "${XCODEBUILD}" -project BGMApp/BGMApp.xcodeproj \
|
||||
-target "Background Music" \
|
||||
-configuration ${CONFIGURATION} \
|
||||
RUN_CLANG_STATIC_ANALYZER=0 \
|
||||
DSTROOT="/" \
|
||||
${XCODEBUILD_OPTIONS} \
|
||||
${CLEAN} "${XCODEBUILD_ACTION}" >> ${LOG_FILE} 2>&1) &
|
||||
|
||||
show_spinner "${BUILD_FAILED_ERROR_MSG}"
|
||||
|
||||
# Fix Background Music.app owner/group.
|
||||
#
|
||||
# We have to run xcodebuild as root to install BGMXPCHelper because it installs to directories
|
||||
# owned by root. But that means the build directory gets created by root, and since BGMApp uses the
|
||||
# same build directory we have to run xcodebuild as root to install BGMApp as well.
|
||||
#
|
||||
# TODO: Can't we just chown -R the build dir before we install BGMApp? Then we wouldn't have to
|
||||
# install BGMApp as root. (But maybe still handle the unlikely case of APP_PATH not being
|
||||
# user-writable.)
|
||||
sudo chown -R "$(whoami):admin" "${APP_PATH}/${APP_DIR}"
|
||||
if [[ "${XCODEBUILD_ACTION}" == "install" ]]; then
|
||||
# Fix Background Music.app owner/group.
|
||||
#
|
||||
# We have to run xcodebuild as root to install BGMXPCHelper because it installs to directories
|
||||
# owned by root. But that means the build directory gets created by root, and since BGMApp uses
|
||||
# the same build directory we have to run xcodebuild as root to install BGMApp as well.
|
||||
#
|
||||
# TODO: Can't we just chown -R the build dir before we install BGMApp? Then we wouldn't have to
|
||||
# install BGMApp as root. (But maybe still handle the unlikely case of APP_PATH not being
|
||||
# user-writable.)
|
||||
sudo chown -R "$(whoami):admin" "${APP_PATH}/${APP_DIR}"
|
||||
|
||||
# Fix the build directories' owner/group. This is mainly so the whole source directory can be
|
||||
# deleted easily after installing.
|
||||
sudo chown -R "$(whoami):admin" "BGMApp/build" "BGMDriver/build"
|
||||
# Fix the build directories' owner/group. This is mainly so the whole source directory can be
|
||||
# deleted easily after installing.
|
||||
sudo chown -R "$(whoami):admin" "BGMApp/build" "BGMDriver/build"
|
||||
|
||||
# Restart coreaudiod.
|
||||
# Restart coreaudiod.
|
||||
|
||||
echo "Restarting coreaudiod to load the virtual audio device." \
|
||||
| tee -a ${LOG_FILE}
|
||||
echo "Restarting coreaudiod to load the virtual audio device." \
|
||||
| tee -a ${LOG_FILE}
|
||||
|
||||
# The extra or-clauses are fallback versions of the command that restarts coreaudiod. Apparently
|
||||
# some of these commands don't work with older versions of launchctl, so I figure there's no harm in
|
||||
# trying a bunch of different ways (which should all work).
|
||||
(sudo launchctl kill SIGTERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill TERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill 15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill -15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
(sudo launchctl unload "${COREAUDIOD_PLIST}" &>/dev/null && \
|
||||
sudo launchctl load "${COREAUDIOD_PLIST}" &>/dev/null) || \
|
||||
sudo killall coreaudiod &>/dev/null) && \
|
||||
sleep 5
|
||||
# The extra or-clauses are fallback versions of the command that restarts coreaudiod. Apparently
|
||||
# some of these commands don't work with older versions of launchctl, so I figure there's no
|
||||
# harm in trying a bunch of different ways (which should all work).
|
||||
(sudo launchctl kill SIGTERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill TERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill 15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
sudo launchctl kill -15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
(sudo launchctl unload "${COREAUDIOD_PLIST}" &>/dev/null && \
|
||||
sudo launchctl load "${COREAUDIOD_PLIST}" &>/dev/null) || \
|
||||
sudo killall coreaudiod &>/dev/null) && \
|
||||
sleep 5
|
||||
|
||||
# Invalidate sudo ticket
|
||||
sudo -k
|
||||
# Invalidate sudo ticket
|
||||
sudo -k
|
||||
|
||||
# Open BGMApp.
|
||||
#
|
||||
# I'd rather not open BGMApp here, or at least ask first, but you have to change your default audio
|
||||
# device after restarting coreaudiod and this is the easiest way.
|
||||
echo "Launching Background Music."
|
||||
# Open BGMApp. We have to change the default audio device after restarting coreaudiod and this
|
||||
# is the easiest way.
|
||||
echo "Launching Background Music."
|
||||
|
||||
ERROR_MSG="${BGMAPP_FAILED_TO_START_ERROR_MSG}"
|
||||
open "${APP_PATH}/${APP_DIR}"
|
||||
ERROR_MSG="${BGMAPP_FAILED_TO_START_ERROR_MSG}"
|
||||
open "${APP_PATH}/${APP_DIR}"
|
||||
|
||||
# Ignore script errors from this point.
|
||||
disable_error_handling
|
||||
# Ignore script errors from this point.
|
||||
disable_error_handling
|
||||
|
||||
# Wait up to 5 seconds for Background Music to start.
|
||||
(trap 'exit 1' TERM
|
||||
while ! (ps -Ao ucomm= | grep 'Background Music' > /dev/null); do
|
||||
sleep 1
|
||||
done) &
|
||||
show_spinner "${BGMAPP_FAILED_TO_START_ERROR_MSG}" 5
|
||||
# Wait up to 5 seconds for Background Music to start.
|
||||
(trap 'exit 1' TERM
|
||||
while ! (ps -Ao ucomm= | grep 'Background Music' > /dev/null); do
|
||||
sleep 1
|
||||
done) &
|
||||
show_spinner "${BGMAPP_FAILED_TO_START_ERROR_MSG}" 5
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
|
||||
|
|
138
package.sh
Executable file
138
package.sh
Executable file
|
@ -0,0 +1,138 @@
|
|||
#!/bin/bash
|
||||
# vim: tw=100:
|
||||
|
||||
# This file is part of Background Music.
|
||||
#
|
||||
# Background Music is free software: you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# Background Music is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Background Music. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# package.sh
|
||||
#
|
||||
# Copyright © 2017 Kyle Neideck
|
||||
# Copyright © 2016, 2017 Takayama Fumihiko
|
||||
#
|
||||
# Build Background Music and package it into a .pkg file and a .zip of the debug symbols (dSYM).
|
||||
#
|
||||
# Based on https://github.com/tekezo/Karabiner-Elements/blob/master/make-package.sh
|
||||
#
|
||||
|
||||
# TODO: Code signing. See `man pkgbuild`.
|
||||
|
||||
PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"; export PATH
|
||||
|
||||
# Sets all dirs in $1 to 755 (rwxr-xr-x) and all files in $1 to 644 (rw-r--r--).
|
||||
set_permissions() {
|
||||
find "$1" -print0 | while read -d $'\0' filepath; do
|
||||
filename="${filepath##*/}"
|
||||
|
||||
if [ -d "$filepath" ]; then
|
||||
chmod -h 755 "$filepath"
|
||||
else
|
||||
chmod -h 644 "$filepath"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# --------------------------------------------------
|
||||
|
||||
# Build
|
||||
bash build_and_install.sh -b
|
||||
|
||||
version="$(/usr/libexec/PlistBuddy \
|
||||
-c "Print CFBundleShortVersionString" \
|
||||
"BGMApp/build/Release/Background Music.app/Contents/Info.plist")"
|
||||
|
||||
out_dir="Background-Music-$version"
|
||||
rm -rf "$out_dir"
|
||||
mkdir "$out_dir"
|
||||
|
||||
# Separate the debug symbols and the .app
|
||||
echo "Archiving debug symbols"
|
||||
|
||||
dsym_archive="$out_dir/Background Music.dSYM-$version.zip"
|
||||
mv "BGMApp/build/Release/Background Music.app/Contents/MacOS/Background Music.dSYM" \
|
||||
"Background Music.dSYM"
|
||||
zip -r "$dsym_archive" "Background Music.dSYM"
|
||||
rm -r "Background Music.dSYM"
|
||||
|
||||
# --------------------------------------------------
|
||||
|
||||
echo "Copying Files"
|
||||
|
||||
rm -rf "pkgroot"
|
||||
mkdir -p "pkgroot"
|
||||
|
||||
mkdir -p "pkgroot/Library/Audio/Plug-Ins/HAL"
|
||||
cp -R "BGMDriver/build/Release/Background Music Device.driver" "pkgroot/Library/Audio/Plug-Ins/HAL/"
|
||||
|
||||
mkdir -p "pkgroot/Applications"
|
||||
cp -R "BGMApp/build/Release/Background Music.app" "pkgroot/Applications"
|
||||
|
||||
scripts_dir="$(mktemp -d)"
|
||||
cp "pkg/preinstall" "$scripts_dir"
|
||||
cp "pkg/postinstall" "$scripts_dir"
|
||||
cp "BGMApp/BGMXPCHelper/com.bearisdriving.BGM.XPCHelper.plist.template" "$scripts_dir"
|
||||
cp "BGMApp/BGMXPCHelper/safe_install_dir.sh" "$scripts_dir"
|
||||
cp "BGMApp/BGMXPCHelper/post_install.sh" "$scripts_dir"
|
||||
cp -R "BGMApp/build/Release/BGMXPCHelper.xpc" "$scripts_dir"
|
||||
|
||||
set_permissions "pkgroot"
|
||||
chmod 755 "pkgroot/Applications/Background Music.app/Contents/MacOS/Background Music"
|
||||
chmod 755 "pkgroot/Library/Audio/Plug-Ins/HAL/Background Music Device.driver/Contents/MacOS/Background Music Device"
|
||||
|
||||
set_permissions "$scripts_dir"
|
||||
chmod 755 "$scripts_dir/preinstall"
|
||||
chmod 755 "$scripts_dir/postinstall"
|
||||
chmod 755 "$scripts_dir/BGMXPCHelper.xpc/Contents/MacOS/BGMXPCHelper"
|
||||
|
||||
rm -rf "pkgres"
|
||||
mkdir -p "pkgres"
|
||||
cp "Images/FermataIcon.pdf" "pkgres"
|
||||
|
||||
sed "s/{{VERSION}}/$version/g" "pkg/Distribution.xml.template" > "pkg/Distribution.xml"
|
||||
|
||||
# --------------------------------------------------
|
||||
|
||||
pkg="$out_dir/BackgroundMusic-$version.pkg"
|
||||
pkg_identifier="com.bearisdriving.BGM"
|
||||
|
||||
echo "Creating $pkg"
|
||||
|
||||
pkgbuild \
|
||||
--root "pkgroot" \
|
||||
--component-plist "pkg/pkgbuild.plist" \
|
||||
--identifier "$pkg_identifier" \
|
||||
--scripts "$scripts_dir" \
|
||||
--version "$version" \
|
||||
--install-location "/" \
|
||||
"$out_dir/Installer.pkg"
|
||||
|
||||
productbuild \
|
||||
--distribution "pkg/Distribution.xml" \
|
||||
--resources "pkgres" \
|
||||
--package-path "$out_dir" \
|
||||
"$pkg"
|
||||
|
||||
rm -f "$out_dir/Installer.pkg"
|
||||
rm -rf "pkgroot"
|
||||
rm -rf "pkgres"
|
||||
rm -f "pkg/Distribution.xml"
|
||||
|
||||
# Print checksums
|
||||
echo "MD5 checksums:"
|
||||
md5 {"$pkg","$dsym_archive"}
|
||||
echo "SHA256 checksums:"
|
||||
shasum -a 256 {"$pkg","$dsym_archive"}
|
||||
|
||||
|
45
pkg/Distribution.xml.template
Normal file
45
pkg/Distribution.xml.template
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<installer-gui-script minSpecVersion="1">
|
||||
<title>Background Music {{VERSION}}</title>
|
||||
|
||||
<volume-check>
|
||||
<allowed-os-versions>
|
||||
<!-- TODO: Get this from the Xcode project files instead of hardcoding it. -->
|
||||
<os-version min="10.9" />
|
||||
</allowed-os-versions>
|
||||
</volume-check>
|
||||
|
||||
<!--
|
||||
Do not specify <domains>.
|
||||
Installer does not show "OS X version X.Y.Z or later is required" message when <domains> exists.
|
||||
<domains enable_anywhere="false" enable_currentUserHome="false" enable_localSystem="true" />
|
||||
-->
|
||||
|
||||
<pkg-ref id="com.bearisdriving.BGM"/>
|
||||
|
||||
<options customize="never" require-scripts="false" />
|
||||
|
||||
<choices-outline>
|
||||
<line choice="default">
|
||||
<line choice="com.bearisdriving.BGM" />
|
||||
</line>
|
||||
</choices-outline>
|
||||
|
||||
<choice id="default"/>
|
||||
|
||||
<choice id="com.bearisdriving.BGM" visible="false">
|
||||
<pkg-ref id="com.bearisdriving.BGM" />
|
||||
</choice>
|
||||
|
||||
<pkg-ref id="com.bearisdriving.BGM" version="{{VERSION}}">Installer.pkg</pkg-ref>
|
||||
|
||||
<pkg-ref id="com.bearisdriving.BGM">
|
||||
<must-close>
|
||||
<app id="com.bearisdriving.BGM.App" />
|
||||
</must-close>
|
||||
</pkg-ref>
|
||||
|
||||
<background file="FermataIcon.pdf" alignment="bottomleft" />
|
||||
</installer-gui-script>
|
||||
|
||||
|
14
pkg/pkgbuild.plist
Normal file
14
pkg/pkgbuild.plist
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array>
|
||||
<dict>
|
||||
<key>RootRelativeBundlePath</key> <string>Applications/Background Music.app</string>
|
||||
<key>BundleHasStrictIdentifier</key> <false/>
|
||||
<key>BundleIsRelocatable</key> <false/>
|
||||
<key>BundleIsVersionChecked</key> <false/>
|
||||
<key>BundleOverwriteAction</key> <string>upgrade</string>
|
||||
</dict>
|
||||
</array>
|
||||
</plist>
|
||||
|
55
pkg/postinstall
Executable file
55
pkg/postinstall
Executable file
|
@ -0,0 +1,55 @@
|
|||
#!/bin/sh
|
||||
# vim: tw=100:
|
||||
|
||||
# This file is part of Background Music.
|
||||
#
|
||||
# Background Music is free software: you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# Background Music is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Background Music. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# preinstall
|
||||
#
|
||||
# Copyright © 2017 Kyle Neideck
|
||||
#
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin; export PATH
|
||||
|
||||
dest_volume="$3"
|
||||
xpc_helper_path="$(bash safe_install_dir.sh -y)"
|
||||
|
||||
logger "Installing BGMXPCHelper to $xpc_helper_path"
|
||||
cp -Rf "BGMXPCHelper.xpc" "$xpc_helper_path"
|
||||
|
||||
# TODO: Fail the install and show an error message if this fails.
|
||||
bash "post_install.sh" "$xpc_helper_path" "BGMXPCHelper.xpc/Contents/MacOS/BGMXPCHelper" "."
|
||||
|
||||
# TODO: Verify the installed files, their permissions, the _BGMXPCHelper user/group, etc.
|
||||
|
||||
# The extra or-clauses are fallback versions of the command that restarts coreaudiod. Apparently
|
||||
# some of these commands don't work with older versions of launchctl, so I figure there's no
|
||||
# harm in trying a bunch of different ways (which should all work).
|
||||
(launchctl kill SIGTERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
launchctl kill TERM system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
launchctl kill 15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
launchctl kill -15 system/com.apple.audio.coreaudiod &>/dev/null || \
|
||||
(launchctl unload "$coreaudiod_plist" &>/dev/null && \
|
||||
launchctl load "$coreaudiod_plist" &>/dev/null) || \
|
||||
killall coreaudiod &>/dev/null) && \
|
||||
sleep 5
|
||||
|
||||
open "${dest_volume}/Applications/Background Music.app"
|
||||
|
||||
# The installer plays a sound when it finishes, so give BGMApp a second to launch.
|
||||
sleep 1
|
||||
|
||||
|
55
pkg/preinstall
Executable file
55
pkg/preinstall
Executable file
|
@ -0,0 +1,55 @@
|
|||
#!/bin/sh
|
||||
# vim: tw=100:
|
||||
|
||||
# This file is part of Background Music.
|
||||
#
|
||||
# Background Music is free software: you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# Background Music is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Background Music. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# preinstall
|
||||
#
|
||||
# Copyright © 2017 Kyle Neideck
|
||||
#
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin; export PATH
|
||||
|
||||
# Show a warning if we can't find a safe dir to install BGMXPCHelper in. Should be very unlikely.
|
||||
xpc_helper_path="$(bash safe_install_dir.sh -y)"
|
||||
|
||||
if [ "$(bash safe_install_dir.sh "$xpc_helper_path")" != "1" ]; then
|
||||
# TODO: This message could be more user friendly.
|
||||
msg="We need to install a helper app called BGMXPCHelper to ${xpc_helper_path}, but it may not "
|
||||
msg+="be secure to do so.\n\n"
|
||||
msg+="${xpc_helper_path} and all of its parent directories should be owned by 'root', with the "
|
||||
msg+="group 'wheel', and have permissions 755 (rwxr-xr-x).\n\n"
|
||||
msg+="Background Music will still work if you decide to continue."
|
||||
|
||||
if ! osascript <<EOT
|
||||
tell application id "com.apple.systemuiserver"
|
||||
display alert "Warning" \
|
||||
message "$msg" \
|
||||
buttons {"Cancel", "Install Anyway"} \
|
||||
default button "Cancel" \
|
||||
cancel button "Cancel" \
|
||||
as warning
|
||||
end tell
|
||||
EOT
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
|
Loading…
Reference in a new issue