From 57bac692bee94e2af1667722e485a10e5c7c8ad3 Mon Sep 17 00:00:00 2001 From: Tobias Hagemann Date: Mon, 27 May 2024 19:55:55 +0200 Subject: [PATCH] Refactored launch service code into its own class --- .../Integrations.xcodeproj/project.pbxproj | 8 ++ src/main/native/SKYLaunchService.h | 17 +++ src/main/native/SKYLaunchService.m | 128 ++++++++++++++++++ ...macos_autostart_MacLaunchServices_Native.m | 120 +--------------- 4 files changed, 157 insertions(+), 116 deletions(-) create mode 100644 src/main/native/SKYLaunchService.h create mode 100644 src/main/native/SKYLaunchService.m diff --git a/src/main/native/Integrations.xcodeproj/project.pbxproj b/src/main/native/Integrations.xcodeproj/project.pbxproj index 32103e4..a1c46cb 100644 --- a/src/main/native/Integrations.xcodeproj/project.pbxproj +++ b/src/main/native/Integrations.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 74BEF1852C0384FB006731AC /* SKYLaunchService.m in Sources */ = {isa = PBXBuildFile; fileRef = 74BEF1842C0384FB006731AC /* SKYLaunchService.m */; }; + 74BEF1862C0384FB006731AC /* SKYLaunchService.h in Headers */ = {isa = PBXBuildFile; fileRef = 74BEF1832C0384FB006731AC /* SKYLaunchService.h */; }; 74CF2E7B254C295A006266D6 /* org_cryptomator_macos_autostart_MacLaunchServices_Native.m in Sources */ = {isa = PBXBuildFile; fileRef = 74CF2E7A254C295A006266D6 /* org_cryptomator_macos_autostart_MacLaunchServices_Native.m */; }; 9E0819C91D75CABC000C89E6 /* org_cryptomator_macos_keychain_MacKeychain_Native.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E0819C71D75CABC000C89E6 /* org_cryptomator_macos_keychain_MacKeychain_Native.m */; }; 9E21340025542735006EA872 /* org_cryptomator_macos_uiappearance_AppAppearance_Native.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E2133FF25542735006EA872 /* org_cryptomator_macos_uiappearance_AppAppearance_Native.m */; }; @@ -19,6 +21,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 74BEF1832C0384FB006731AC /* SKYLaunchService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SKYLaunchService.h; sourceTree = ""; }; + 74BEF1842C0384FB006731AC /* SKYLaunchService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SKYLaunchService.m; sourceTree = ""; }; 74CF2E7A254C295A006266D6 /* org_cryptomator_macos_autostart_MacLaunchServices_Native.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = org_cryptomator_macos_autostart_MacLaunchServices_Native.m; sourceTree = ""; }; 9E0819B71D748ECC000C89E6 /* libIntegrations.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libIntegrations.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 9E0819C71D75CABC000C89E6 /* org_cryptomator_macos_keychain_MacKeychain_Native.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = org_cryptomator_macos_keychain_MacKeychain_Native.m; sourceTree = ""; }; @@ -54,6 +58,8 @@ 9E21341025542ECE006EA872 /* SKYAppearanceNotifier.m */, 9E213409255429CA006EA872 /* SKYAppearanceObserver.h */, 9E21340A255429CA006EA872 /* SKYAppearanceObserver.m */, + 74BEF1832C0384FB006731AC /* SKYLaunchService.h */, + 74BEF1842C0384FB006731AC /* SKYLaunchService.m */, 9E0819B81D748ECC000C89E6 /* Products */, ); sourceTree = ""; @@ -74,6 +80,7 @@ buildActionMask = 2147483647; files = ( 9E21341125542ECE006EA872 /* SKYAppearanceNotifier.h in Headers */, + 74BEF1862C0384FB006731AC /* SKYLaunchService.h in Headers */, 9E21340B255429CA006EA872 /* SKYAppearanceObserver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -135,6 +142,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 74BEF1852C0384FB006731AC /* SKYLaunchService.m in Sources */, 9EACB1B425557865000F3214 /* org_cryptomator_macos_tray_ActivationPolicy_Native.m in Sources */, 74CF2E7B254C295A006266D6 /* org_cryptomator_macos_autostart_MacLaunchServices_Native.m in Sources */, 9E21340C255429CA006EA872 /* SKYAppearanceObserver.m in Sources */, diff --git a/src/main/native/SKYLaunchService.h b/src/main/native/SKYLaunchService.h new file mode 100644 index 0000000..bffb7e0 --- /dev/null +++ b/src/main/native/SKYLaunchService.h @@ -0,0 +1,17 @@ +// +// SKYLaunchService.h +// Integrations +// +// Created by Tobias Hagemann on 26.05.24. +// Copyright © 2024 Cryptomator. All rights reserved. +// + +#import + +@interface SKYLaunchService : NSObject + ++ (BOOL)isLoginItemEnabled; ++ (BOOL)enableLoginItem; ++ (BOOL)disableLoginItem; + +@end diff --git a/src/main/native/SKYLaunchService.m b/src/main/native/SKYLaunchService.m new file mode 100644 index 0000000..a2fb2f2 --- /dev/null +++ b/src/main/native/SKYLaunchService.m @@ -0,0 +1,128 @@ +// +// SKYLaunchService.m +// Integrations +// +// Created by Tobias Hagemann on 26.05.24. +// Copyright © 2024 Cryptomator. All rights reserved. +// + +#import "SKYLaunchService.h" +#import + +@implementation SKYLaunchService + ++ (BOOL)isLoginItemEnabled { + if (@available(macOS 13, *)) { + if (SMAppService.mainAppService.status == SMAppServiceStatusEnabled) { + return YES; + } else if ([self isLegacyLoginItemEnabled]) { + // migrate legacy login item + [self disableLegacyLoginItem]; + return [self enableLoginItem]; + } else { + return NO; + } + } else { // macOS < 13 + return [self isLegacyLoginItemEnabled]; + } +} + ++ (BOOL)enableLoginItem { + if (@available(macOS 13, *)) { + NSError *error; + if ([SMAppService.mainAppService registerAndReturnError:&error]) { + return YES; + } else { + NSLog(@"Failed to register login item: %@", error.localizedDescription); + return NO; + } + } else { // macOS < 13 + return [self enableLegacyLoginItem]; + } +} + ++ (BOOL)disableLoginItem { + if (@available(macOS 13, *)) { + NSError *error; + if ([SMAppService.mainAppService unregisterAndReturnError:&error]) { + return YES; + } else { + NSLog(@"Failed to unregister login item: %@", error.localizedDescription); + return NO; + } + } else { // macOS < 13 + return [self disableLegacyLoginItem]; + } +} + +#pragma mark - Legacy + ++ (BOOL)isLegacyLoginItemEnabled { + LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); + NSString *applicationPath = NSBundle.mainBundle.bundlePath; + if (sharedFileList) { + UInt32 seedValue; + NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue)); + for (id sharedFile in sharedFileListArray) { + LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile; + CFURLRef applicationPathURL = NULL; + LSSharedFileListItemResolve(sharedFileListItem, 0, (CFURLRef *)&applicationPathURL, NULL); + if (applicationPathURL != NULL) { + NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path]; + CFRelease(applicationPathURL); + if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) { + CFRelease(sharedFileList); + return YES; + } + } + } + CFRelease(sharedFileList); + } else { + NSLog(@"Unable to create the shared file list."); + } + return NO; +} + ++ (BOOL)enableLegacyLoginItem { + LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); + NSString *applicationPath = NSBundle.mainBundle.bundlePath; + NSURL *applicationPathURL = [NSURL fileURLWithPath:applicationPath]; + if (sharedFileList) { + LSSharedFileListItemRef sharedFileListItem = LSSharedFileListInsertItemURL(sharedFileList, kLSSharedFileListItemLast, NULL, NULL, (__bridge CFURLRef)applicationPathURL, NULL, NULL); + if (sharedFileListItem) { + CFRelease(sharedFileListItem); + } + CFRelease(sharedFileList); + return YES; + } else { + NSLog(@"Unable to create the shared file list."); + return NO; + } +} + ++ (BOOL)disableLegacyLoginItem { + LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); + NSString *applicationPath = NSBundle.mainBundle.bundlePath; + if (sharedFileList) { + UInt32 seedValue; + NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue)); + for (id sharedFile in sharedFileListArray) { + LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile; + CFURLRef applicationPathURL; + if (LSSharedFileListItemResolve(sharedFileListItem, 0, &applicationPathURL, NULL) == noErr) { + NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path]; + if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) { + LSSharedFileListItemRemove(sharedFileList, sharedFileListItem); + } + CFRelease(applicationPathURL); + } + } + CFRelease(sharedFileList); + return YES; + } else { + NSLog(@"Unable to create the shared file list."); + return NO; + } +} + +@end diff --git a/src/main/native/org_cryptomator_macos_autostart_MacLaunchServices_Native.m b/src/main/native/org_cryptomator_macos_autostart_MacLaunchServices_Native.m index 5eeab27..2c22932 100644 --- a/src/main/native/org_cryptomator_macos_autostart_MacLaunchServices_Native.m +++ b/src/main/native/org_cryptomator_macos_autostart_MacLaunchServices_Native.m @@ -7,128 +7,16 @@ // #import "org_cryptomator_macos_autostart_MacLaunchServices_Native.h" -#import -#import - -static void migrateSharedFileListLoginItem(void) { - LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); - NSString *applicationPath = NSBundle.mainBundle.bundlePath; - if (sharedFileList) { - UInt32 seedValue; - NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue)); - for (id sharedFile in sharedFileListArray) { - LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile; - CFURLRef applicationPathURL; - if (LSSharedFileListItemResolve(sharedFileListItem, 0, &applicationPathURL, NULL) == noErr) { - NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path]; - if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) { - LSSharedFileListItemRemove(sharedFileList, sharedFileListItem); - NSError* error = nil; - if (![[SMAppService mainAppService] registerAndReturnError: & error]) { - NSLog(@"Failed to add login item: %@", error.localizedDescription); - } - } - CFRelease(applicationPathURL); - } - } - CFRelease(sharedFileList); - } else { - NSLog(@"Unable to create the shared file list."); - } -} +#import "SKYLaunchService.h" JNIEXPORT jboolean JNICALL Java_org_cryptomator_macos_autostart_MacLaunchServices_00024Native_isLoginItemEnabled(JNIEnv *env, jobject thisObj) { - if (@available(macOS 13, *)) { - if ([[SMAppService mainAppService] status] == SMAppServiceStatusEnabled) { - return YES; - } - migrateSharedFileListLoginItem(); - return [[SMAppService mainAppService] status] == SMAppServiceStatusEnabled ? YES : NO; - } else { // macOS < 13 - LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); - NSString *applicationPath = NSBundle.mainBundle.bundlePath; - if (sharedFileList) { - UInt32 seedValue; - NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue)); - for (id sharedFile in sharedFileListArray) { - LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile; - CFURLRef applicationPathURL = NULL; - LSSharedFileListItemResolve(sharedFileListItem, 0, (CFURLRef *)&applicationPathURL, NULL); - if (applicationPathURL != NULL) { - NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path]; - CFRelease(applicationPathURL); - if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) { - CFRelease(sharedFileList); - return YES; - } - } - } - CFRelease(sharedFileList); - } else { - NSLog(@"Unable to create the shared file list."); - } - return NO; - } + return [SKYLaunchService isLoginItemEnabled]; } JNIEXPORT jboolean JNICALL Java_org_cryptomator_macos_autostart_MacLaunchServices_00024Native_enableLoginItem(JNIEnv *env, jobject thisObj) { - if (@available(macOS 13, *)) { - NSError* error = nil; - if (![[SMAppService mainAppService] registerAndReturnError: & error]) { - NSLog(@"Failed to add login item: %@", error.localizedDescription); - return NO; - } else { - return YES; - } - } else { // macOS < 13 - LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); - NSString *applicationPath = NSBundle.mainBundle.bundlePath; - NSURL *applicationPathURL = [NSURL fileURLWithPath:applicationPath]; - if (sharedFileList) { - LSSharedFileListItemRef sharedFileListItem = LSSharedFileListInsertItemURL(sharedFileList, kLSSharedFileListItemLast, NULL, NULL, (__bridge CFURLRef)applicationPathURL, NULL, NULL); - if (sharedFileListItem) { - CFRelease(sharedFileListItem); - } - CFRelease(sharedFileList); - return YES; - } else { - NSLog(@"Unable to create the shared file list."); - return NO; - } - } + return [SKYLaunchService enableLoginItem]; } JNIEXPORT jboolean JNICALL Java_org_cryptomator_macos_autostart_MacLaunchServices_00024Native_disableLoginItem(JNIEnv *env, jobject thisObj) { - if (@available(macOS 13, *)) { - NSError* error = nil; - if (![[SMAppService mainAppService] unregisterAndReturnError: & error]) { - NSLog(@"Failed to remove login item: %@", error.localizedDescription); - return NO; - } else { - return YES; - } - } else { // macOS < 13 - LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); - NSString *applicationPath = NSBundle.mainBundle.bundlePath; - if (sharedFileList) { - UInt32 seedValue; - NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue)); - for (id sharedFile in sharedFileListArray) { - LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile; - CFURLRef applicationPathURL; - if (LSSharedFileListItemResolve(sharedFileListItem, 0, &applicationPathURL, NULL) == noErr) { - NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path]; - if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) { - LSSharedFileListItemRemove(sharedFileList, sharedFileListItem); - } - CFRelease(applicationPathURL); - } - } - CFRelease(sharedFileList); - return YES; - } else { - NSLog(@"Unable to create the shared file list."); - return NO; - } - } + return [SKYLaunchService disableLoginItem]; }