From e88d016f1d2aafee525589aafcb59f5890b90d3a Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Sat, 13 Jan 2024 00:16:33 +0200 Subject: [PATCH] macOS changes --- src/fah/client/osx/OSXOSImpl.cpp | 113 +++++++++++-------------------- src/fah/client/osx/OSXOSImpl.h | 29 ++++---- 2 files changed, 55 insertions(+), 87 deletions(-) diff --git a/src/fah/client/osx/OSXOSImpl.cpp b/src/fah/client/osx/OSXOSImpl.cpp index 3cad382..1c32c3e 100644 --- a/src/fah/client/osx/OSXOSImpl.cpp +++ b/src/fah/client/osx/OSXOSImpl.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -55,52 +54,54 @@ using namespace std; static const CFTimeInterval kCFTimeIntervalMax = - std::numeric_limits::max(); + numeric_limits::max(); enum { kDisplayPowerUnknown = -1, - kDisplayPowerOff = 0, - kDisplayPowerDimmed = 3, - kDisplayPowerOn = 4 + kDisplayPowerOff = 0, + kDisplayPowerDimmed = 3, + kDisplayPowerOn = 4 }; namespace { #pragma mark c callbacks - void consoleUserCB(SCDynamicStoreRef s, CFArrayRef keys, void *info) { OSXOSImpl::instance().consoleUserChanged(s, keys, info); } - void displayPowerCB(void *ctx, io_service_t service, - natural_t mtype, void *marg) { + + void displayPowerCB( + void *ctx, io_service_t service, natural_t mtype, void *marg) { OSXOSImpl::instance().displayPowerChanged(ctx, service, mtype, marg); } + void updateTimerCB(CFRunLoopTimerRef timer, void *info) { OSXOSImpl::instance().updateTimerFired(timer, info); } + void heartbeatTimerCB(CFRunLoopTimerRef timer, void *info) { LOG_DEBUG(5, "heartbeat on thread " << pthread_self() << (pthread_main_np() ? " main" : "")); } + void noteQuitCB(CFNotificationCenterRef center, void *observer, CFNotificationName name, const void *object, CFDictionaryRef info) { - std::string n = CFStringGetCStringPtr(name, kCFStringEncodingUTF8); - LOG_INFO(3, "Received notification " << n); + LOG_INFO(3, "Received notification " + << CFStringGetCStringPtr(name, kCFStringEncodingUTF8)); OSXOSImpl::instance().requestExit(); } - } OSXOSImpl *OSXOSImpl::singleton = 0; -OSXOSImpl::OSXOSImpl(App &app) : OS(app), consoleUser(CFSTR("unknown")) { +OSXOSImpl::OSXOSImpl(App &app) : OS(app), consoleUser("unknown") { if (singleton) THROW("There can be only one OSXOSImpl"); singleton = this; initialize(); @@ -109,10 +110,7 @@ OSXOSImpl::OSXOSImpl(App &app) : OS(app), consoleUser(CFSTR("unknown")) { OSXOSImpl::~OSXOSImpl() { // Stop any update timer - if (updateTimer) { - CFRunLoopTimerInvalidate(updateTimer); - CFRelease(updateTimer); - } + if (updateTimer) CFRunLoopTimerInvalidate(updateTimer); // Deregister for display power changes if (displayWrangler) IOObjectRelease(displayWrangler); @@ -122,21 +120,11 @@ OSXOSImpl::~OSXOSImpl() { kCFRunLoopDefaultMode); if (displayNotePort) IONotificationPortDestroy(displayNotePort); - if (displayNotifier) IOObjectRelease(displayNotifier); // Deregister for console user changes - if (consoleUserRLS) { - CFRunLoopSourceInvalidate(consoleUserRLS); - CFRelease(consoleUserRLS); - } - - if (consoleUserDS) { - SCDynamicStoreSetNotificationKeys(consoleUserDS, 0, 0); - CFRelease(consoleUserDS); - } - - if (consoleUser) CFRelease(consoleUser); + if (consoleUserRLS) CFRunLoopSourceInvalidate(consoleUserRLS); + if (consoleUserDS) SCDynamicStoreSetNotificationKeys(consoleUserDS, 0, 0); CFNotificationCenterRef nc = CFNotificationCenterGetDarwinNotifyCenter(); CFNotificationCenterRemoveEveryObserver(nc, this); @@ -174,18 +162,12 @@ void OSXOSImpl::addHeartbeatTimerToRunLoop(CFRunLoopRef loop) { // note this may fail silently if (!loop) return; - CFRunLoopTimerRef timer = + MacOSRef timer = CFRunLoopTimerCreate(0, 0, 3600, 0, 0, heartbeatTimerCB, 0); - if (timer) { - CFRunLoopAddTimer(loop, timer, kCFRunLoopDefaultMode); - CFRelease(timer); - } + if (timer) CFRunLoopAddTimer(loop, timer, kCFRunLoopDefaultMode); } -const char *OSXOSImpl::getName() const {return "macosx";} - - void OSXOSImpl::dispatch() { if (!pthread_main_np()) THROW("OSXOSImpl::dispatch() must be called on main thread"); @@ -224,8 +206,10 @@ void OSXOSImpl::finishInit() { void OSXOSImpl::updateSystemIdle() { bool shouldBeIdle = displayPower == kDisplayPowerOff || loginwindowIsActive || screensaverIsActive || screenIsLocked; + if (shouldBeIdle == systemIsIdle) return; systemIsIdle = shouldBeIdle; + event->activate(); } @@ -266,6 +250,7 @@ void OSXOSImpl::delayedUpdateSystemIdle(int delay) { } else if (delay < currentDelay) { // Use sooner of current fire date and candidateTime CFAbsoluteTime currentTime = CFRunLoopTimerGetNextFireDate(updateTimer); + if (candidateTime < currentTime) { CFRunLoopTimerSetNextFireDate(updateTimer, candidateTime); currentDelay = delay; @@ -274,7 +259,7 @@ void OSXOSImpl::delayedUpdateSystemIdle(int delay) { } -void OSXOSImpl::displayDidDim() {displayPower = kDisplayPowerDimmed;} +void OSXOSImpl::displayDidDim() {displayPower = kDisplayPowerDimmed;} void OSXOSImpl::displayDidUndim() {displayPower = kDisplayPowerOn;} @@ -321,7 +306,7 @@ void OSXOSImpl::displayPowerChanged(void *context, io_service_t service, int OSXOSImpl::getCurrentDisplayPower() { // will only return values kDisplayPowerUnknown thru kDisplayPowerOn - int state = kDisplayPowerUnknown; + int state = kDisplayPowerUnknown; int maxstate = 4; if (!displayWrangler) @@ -329,9 +314,8 @@ int OSXOSImpl::getCurrentDisplayPower() { (kIOMasterPortDefault, IOServiceNameMatching("IODisplayWrangler")); if (displayWrangler) { - CFMutableDictionaryRef props = 0; - - auto kr = IORegistryEntryCreateCFProperties(displayWrangler, &props, 0, 0); + MacOSRef props; + auto kr = IORegistryEntryCreateCFProperties(displayWrangler, props, 0, 0); if (kr == KERN_SUCCESS) { auto dict = (CFMutableDictionaryRef)CFDictionaryGetValue @@ -357,7 +341,6 @@ int OSXOSImpl::getCurrentDisplayPower() { } } - if (props) CFRelease(props); IOObjectRelease(displayWrangler); displayWrangler = 0; } @@ -424,17 +407,14 @@ bool OSXOSImpl::registerForDisplayPowerNotifications() { } -void OSXOSImpl::consoleUserChanged(SCDynamicStoreRef store, - CFArrayRef changedKeys, void *info) { - if (consoleUser) CFRelease(consoleUser); - consoleUser = SCDynamicStoreCopyConsoleUser(consoleUserDS, 0, 0); +void OSXOSImpl::consoleUserChanged( + SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) { + consoleUser = MacOSString(SCDynamicStoreCopyConsoleUser(consoleUserDS, 0, 0)); - LOG_DEBUG(4, __func__ << "() " << MacOSUtilities::toString(consoleUser)); + LOG_DEBUG(4, __func__ << "() " << (string)consoleUser); bool wasActive = loginwindowIsActive; - loginwindowIsActive = !consoleUser || !CFStringGetLength(consoleUser) || - CFEqual(consoleUser, CFSTR("loginwindow")); - + loginwindowIsActive = consoleUser.empty() || consoleUser == "loginwindow"; bool changed = wasActive != loginwindowIsActive; if (changed || !store) { @@ -450,9 +430,9 @@ bool OSXOSImpl::registerForConsoleUserNotifications() { consoleUserDS = SCDynamicStoreCreate (0, CFSTR("FAHClient Console User Watcher"), consoleUserCB, &context); - CFStringRef consoleUserKey = SCDynamicStoreKeyCreateConsoleUser(0); - CFStringRef values[] = {consoleUserKey}; - CFArrayRef keys = + MacOSString consoleUserKey = SCDynamicStoreKeyCreateConsoleUser(0); + CFStringRef values[] = {(CFStringRef)consoleUserKey}; + MacOSRef keys = CFArrayCreate(0, (const void **)values, 1, &kCFTypeArrayCallBacks); bool ok = consoleUserKey && keys && consoleUserDS; @@ -467,17 +447,12 @@ bool OSXOSImpl::registerForConsoleUserNotifications() { if (!ok) { if (consoleUserDS) { SCDynamicStoreSetNotificationKeys(consoleUserDS, 0, 0); - CFRelease(consoleUserDS); consoleUserDS = 0; } - if (consoleUser) CFRelease(consoleUser); - consoleUser = CFSTR("unknown"); + consoleUser = "unknown"; } - if (consoleUserKey) CFRelease(consoleUserKey); - if (keys) CFRelease(keys); - // Initial consoleUser value will be set in finishInit return ok; } @@ -488,24 +463,16 @@ bool OSXOSImpl::registerForDarwinNotifications() { if (!nc) return false; - std::string user = "nobody"; + string user = "nobody"; struct passwd *pwent = getpwuid(getuid()); if (pwent && pwent->pw_name) user = pwent->pw_name; - std::string key = "org.foldingathome.fahclient." + user + ".stop"; - CFStringRef name = - CFStringCreateWithCString(0, key.c_str(), kCFStringEncodingUTF8); - - if (name) { - CFNotificationCenterAddObserver( - nc, (void *)this, ¬eQuitCB, name, 0, - CFNotificationSuspensionBehaviorCoalesce); - CFRelease(name); + MacOSString name(string("org.foldingathome.fahclient." + user + ".stop")); + CFNotificationCenterAddObserver( + nc, (void *)this, ¬eQuitCB, name, 0, + CFNotificationSuspensionBehaviorCoalesce); - return true; - } - - return false; + return true; } diff --git a/src/fah/client/osx/OSXOSImpl.h b/src/fah/client/osx/OSXOSImpl.h index 48df64e..1552d8b 100644 --- a/src/fah/client/osx/OSXOSImpl.h +++ b/src/fah/client/osx/OSXOSImpl.h @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -46,25 +47,25 @@ namespace FAH { static OSXOSImpl *singleton; std::atomic systemIsIdle = false; - bool screensaverIsActive = false; - bool screenIsLocked = false; - bool loginwindowIsActive = false; + bool screensaverIsActive = false; + bool screenIsLocked = false; + bool loginwindowIsActive = false; io_service_t displayWrangler = 0; - IONotificationPortRef displayNotePort = 0; - CFRunLoopSourceRef displayNoteSource = 0; - io_object_t displayNotifier = 0; + io_object_t displayNotifier = 0; + cb::MacOSRef displayNotePort; + cb::MacOSRef displayNoteSource; - SCDynamicStoreRef consoleUserDS = 0; - CFRunLoopSourceRef consoleUserRLS = 0; - CFStringRef consoleUser = 0; + cb::MacOSRef consoleUserDS; + cb::MacOSRef consoleUserRLS; + std::string consoleUser; - CFRunLoopTimerRef updateTimer = 0; + cb::MacOSRef updateTimer; - int idleDelay = 5; - int currentDelay = 0; + int idleDelay = 5; + int currentDelay = 0; int idleOnLoginwindowDelay = 30; - int displayPower = 0; + int displayPower = 0; public: OSXOSImpl(App &app); @@ -73,7 +74,7 @@ namespace FAH { static OSXOSImpl &instance(); // From OS - const char *getName() const; + const char *getName() const {return "macosx";} bool isSystemIdle() const {return systemIsIdle;} void dispatch();