Skip to content

Commit 57bac69

Browse files
committed
Refactored launch service code into its own class
1 parent 755a3ad commit 57bac69

File tree

4 files changed

+157
-116
lines changed

4 files changed

+157
-116
lines changed

src/main/native/Integrations.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
74BEF1852C0384FB006731AC /* SKYLaunchService.m in Sources */ = {isa = PBXBuildFile; fileRef = 74BEF1842C0384FB006731AC /* SKYLaunchService.m */; };
11+
74BEF1862C0384FB006731AC /* SKYLaunchService.h in Headers */ = {isa = PBXBuildFile; fileRef = 74BEF1832C0384FB006731AC /* SKYLaunchService.h */; };
1012
74CF2E7B254C295A006266D6 /* org_cryptomator_macos_autostart_MacLaunchServices_Native.m in Sources */ = {isa = PBXBuildFile; fileRef = 74CF2E7A254C295A006266D6 /* org_cryptomator_macos_autostart_MacLaunchServices_Native.m */; };
1113
9E0819C91D75CABC000C89E6 /* org_cryptomator_macos_keychain_MacKeychain_Native.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E0819C71D75CABC000C89E6 /* org_cryptomator_macos_keychain_MacKeychain_Native.m */; };
1214
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 @@
1921
/* End PBXBuildFile section */
2022

2123
/* Begin PBXFileReference section */
24+
74BEF1832C0384FB006731AC /* SKYLaunchService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SKYLaunchService.h; sourceTree = "<group>"; };
25+
74BEF1842C0384FB006731AC /* SKYLaunchService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SKYLaunchService.m; sourceTree = "<group>"; };
2226
74CF2E7A254C295A006266D6 /* org_cryptomator_macos_autostart_MacLaunchServices_Native.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = org_cryptomator_macos_autostart_MacLaunchServices_Native.m; sourceTree = "<group>"; };
2327
9E0819B71D748ECC000C89E6 /* libIntegrations.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libIntegrations.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
2428
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 = "<group>"; };
@@ -54,6 +58,8 @@
5458
9E21341025542ECE006EA872 /* SKYAppearanceNotifier.m */,
5559
9E213409255429CA006EA872 /* SKYAppearanceObserver.h */,
5660
9E21340A255429CA006EA872 /* SKYAppearanceObserver.m */,
61+
74BEF1832C0384FB006731AC /* SKYLaunchService.h */,
62+
74BEF1842C0384FB006731AC /* SKYLaunchService.m */,
5763
9E0819B81D748ECC000C89E6 /* Products */,
5864
);
5965
sourceTree = "<group>";
@@ -74,6 +80,7 @@
7480
buildActionMask = 2147483647;
7581
files = (
7682
9E21341125542ECE006EA872 /* SKYAppearanceNotifier.h in Headers */,
83+
74BEF1862C0384FB006731AC /* SKYLaunchService.h in Headers */,
7784
9E21340B255429CA006EA872 /* SKYAppearanceObserver.h in Headers */,
7885
);
7986
runOnlyForDeploymentPostprocessing = 0;
@@ -135,6 +142,7 @@
135142
isa = PBXSourcesBuildPhase;
136143
buildActionMask = 2147483647;
137144
files = (
145+
74BEF1852C0384FB006731AC /* SKYLaunchService.m in Sources */,
138146
9EACB1B425557865000F3214 /* org_cryptomator_macos_tray_ActivationPolicy_Native.m in Sources */,
139147
74CF2E7B254C295A006266D6 /* org_cryptomator_macos_autostart_MacLaunchServices_Native.m in Sources */,
140148
9E21340C255429CA006EA872 /* SKYAppearanceObserver.m in Sources */,

src/main/native/SKYLaunchService.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// SKYLaunchService.h
3+
// Integrations
4+
//
5+
// Created by Tobias Hagemann on 26.05.24.
6+
// Copyright © 2024 Cryptomator. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
11+
@interface SKYLaunchService : NSObject
12+
13+
+ (BOOL)isLoginItemEnabled;
14+
+ (BOOL)enableLoginItem;
15+
+ (BOOL)disableLoginItem;
16+
17+
@end

src/main/native/SKYLaunchService.m

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
//
2+
// SKYLaunchService.m
3+
// Integrations
4+
//
5+
// Created by Tobias Hagemann on 26.05.24.
6+
// Copyright © 2024 Cryptomator. All rights reserved.
7+
//
8+
9+
#import "SKYLaunchService.h"
10+
#import <ServiceManagement/ServiceManagement.h>
11+
12+
@implementation SKYLaunchService
13+
14+
+ (BOOL)isLoginItemEnabled {
15+
if (@available(macOS 13, *)) {
16+
if (SMAppService.mainAppService.status == SMAppServiceStatusEnabled) {
17+
return YES;
18+
} else if ([self isLegacyLoginItemEnabled]) {
19+
// migrate legacy login item
20+
[self disableLegacyLoginItem];
21+
return [self enableLoginItem];
22+
} else {
23+
return NO;
24+
}
25+
} else { // macOS < 13
26+
return [self isLegacyLoginItemEnabled];
27+
}
28+
}
29+
30+
+ (BOOL)enableLoginItem {
31+
if (@available(macOS 13, *)) {
32+
NSError *error;
33+
if ([SMAppService.mainAppService registerAndReturnError:&error]) {
34+
return YES;
35+
} else {
36+
NSLog(@"Failed to register login item: %@", error.localizedDescription);
37+
return NO;
38+
}
39+
} else { // macOS < 13
40+
return [self enableLegacyLoginItem];
41+
}
42+
}
43+
44+
+ (BOOL)disableLoginItem {
45+
if (@available(macOS 13, *)) {
46+
NSError *error;
47+
if ([SMAppService.mainAppService unregisterAndReturnError:&error]) {
48+
return YES;
49+
} else {
50+
NSLog(@"Failed to unregister login item: %@", error.localizedDescription);
51+
return NO;
52+
}
53+
} else { // macOS < 13
54+
return [self disableLegacyLoginItem];
55+
}
56+
}
57+
58+
#pragma mark - Legacy
59+
60+
+ (BOOL)isLegacyLoginItemEnabled {
61+
LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
62+
NSString *applicationPath = NSBundle.mainBundle.bundlePath;
63+
if (sharedFileList) {
64+
UInt32 seedValue;
65+
NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue));
66+
for (id sharedFile in sharedFileListArray) {
67+
LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile;
68+
CFURLRef applicationPathURL = NULL;
69+
LSSharedFileListItemResolve(sharedFileListItem, 0, (CFURLRef *)&applicationPathURL, NULL);
70+
if (applicationPathURL != NULL) {
71+
NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path];
72+
CFRelease(applicationPathURL);
73+
if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) {
74+
CFRelease(sharedFileList);
75+
return YES;
76+
}
77+
}
78+
}
79+
CFRelease(sharedFileList);
80+
} else {
81+
NSLog(@"Unable to create the shared file list.");
82+
}
83+
return NO;
84+
}
85+
86+
+ (BOOL)enableLegacyLoginItem {
87+
LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
88+
NSString *applicationPath = NSBundle.mainBundle.bundlePath;
89+
NSURL *applicationPathURL = [NSURL fileURLWithPath:applicationPath];
90+
if (sharedFileList) {
91+
LSSharedFileListItemRef sharedFileListItem = LSSharedFileListInsertItemURL(sharedFileList, kLSSharedFileListItemLast, NULL, NULL, (__bridge CFURLRef)applicationPathURL, NULL, NULL);
92+
if (sharedFileListItem) {
93+
CFRelease(sharedFileListItem);
94+
}
95+
CFRelease(sharedFileList);
96+
return YES;
97+
} else {
98+
NSLog(@"Unable to create the shared file list.");
99+
return NO;
100+
}
101+
}
102+
103+
+ (BOOL)disableLegacyLoginItem {
104+
LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
105+
NSString *applicationPath = NSBundle.mainBundle.bundlePath;
106+
if (sharedFileList) {
107+
UInt32 seedValue;
108+
NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue));
109+
for (id sharedFile in sharedFileListArray) {
110+
LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile;
111+
CFURLRef applicationPathURL;
112+
if (LSSharedFileListItemResolve(sharedFileListItem, 0, &applicationPathURL, NULL) == noErr) {
113+
NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path];
114+
if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) {
115+
LSSharedFileListItemRemove(sharedFileList, sharedFileListItem);
116+
}
117+
CFRelease(applicationPathURL);
118+
}
119+
}
120+
CFRelease(sharedFileList);
121+
return YES;
122+
} else {
123+
NSLog(@"Unable to create the shared file list.");
124+
return NO;
125+
}
126+
}
127+
128+
@end

src/main/native/org_cryptomator_macos_autostart_MacLaunchServices_Native.m

Lines changed: 4 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -7,128 +7,16 @@
77
//
88

99
#import "org_cryptomator_macos_autostart_MacLaunchServices_Native.h"
10-
#import <Foundation/Foundation.h>
11-
#import <ServiceManagement/ServiceManagement.h>
12-
13-
static void migrateSharedFileListLoginItem(void) {
14-
LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
15-
NSString *applicationPath = NSBundle.mainBundle.bundlePath;
16-
if (sharedFileList) {
17-
UInt32 seedValue;
18-
NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue));
19-
for (id sharedFile in sharedFileListArray) {
20-
LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile;
21-
CFURLRef applicationPathURL;
22-
if (LSSharedFileListItemResolve(sharedFileListItem, 0, &applicationPathURL, NULL) == noErr) {
23-
NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path];
24-
if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) {
25-
LSSharedFileListItemRemove(sharedFileList, sharedFileListItem);
26-
NSError* error = nil;
27-
if (![[SMAppService mainAppService] registerAndReturnError: & error]) {
28-
NSLog(@"Failed to add login item: %@", error.localizedDescription);
29-
}
30-
}
31-
CFRelease(applicationPathURL);
32-
}
33-
}
34-
CFRelease(sharedFileList);
35-
} else {
36-
NSLog(@"Unable to create the shared file list.");
37-
}
38-
}
10+
#import "SKYLaunchService.h"
3911

4012
JNIEXPORT jboolean JNICALL Java_org_cryptomator_macos_autostart_MacLaunchServices_00024Native_isLoginItemEnabled(JNIEnv *env, jobject thisObj) {
41-
if (@available(macOS 13, *)) {
42-
if ([[SMAppService mainAppService] status] == SMAppServiceStatusEnabled) {
43-
return YES;
44-
}
45-
migrateSharedFileListLoginItem();
46-
return [[SMAppService mainAppService] status] == SMAppServiceStatusEnabled ? YES : NO;
47-
} else { // macOS < 13
48-
LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
49-
NSString *applicationPath = NSBundle.mainBundle.bundlePath;
50-
if (sharedFileList) {
51-
UInt32 seedValue;
52-
NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue));
53-
for (id sharedFile in sharedFileListArray) {
54-
LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile;
55-
CFURLRef applicationPathURL = NULL;
56-
LSSharedFileListItemResolve(sharedFileListItem, 0, (CFURLRef *)&applicationPathURL, NULL);
57-
if (applicationPathURL != NULL) {
58-
NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path];
59-
CFRelease(applicationPathURL);
60-
if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) {
61-
CFRelease(sharedFileList);
62-
return YES;
63-
}
64-
}
65-
}
66-
CFRelease(sharedFileList);
67-
} else {
68-
NSLog(@"Unable to create the shared file list.");
69-
}
70-
return NO;
71-
}
13+
return [SKYLaunchService isLoginItemEnabled];
7214
}
7315

7416
JNIEXPORT jboolean JNICALL Java_org_cryptomator_macos_autostart_MacLaunchServices_00024Native_enableLoginItem(JNIEnv *env, jobject thisObj) {
75-
if (@available(macOS 13, *)) {
76-
NSError* error = nil;
77-
if (![[SMAppService mainAppService] registerAndReturnError: & error]) {
78-
NSLog(@"Failed to add login item: %@", error.localizedDescription);
79-
return NO;
80-
} else {
81-
return YES;
82-
}
83-
} else { // macOS < 13
84-
LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
85-
NSString *applicationPath = NSBundle.mainBundle.bundlePath;
86-
NSURL *applicationPathURL = [NSURL fileURLWithPath:applicationPath];
87-
if (sharedFileList) {
88-
LSSharedFileListItemRef sharedFileListItem = LSSharedFileListInsertItemURL(sharedFileList, kLSSharedFileListItemLast, NULL, NULL, (__bridge CFURLRef)applicationPathURL, NULL, NULL);
89-
if (sharedFileListItem) {
90-
CFRelease(sharedFileListItem);
91-
}
92-
CFRelease(sharedFileList);
93-
return YES;
94-
} else {
95-
NSLog(@"Unable to create the shared file list.");
96-
return NO;
97-
}
98-
}
17+
return [SKYLaunchService enableLoginItem];
9918
}
10019

10120
JNIEXPORT jboolean JNICALL Java_org_cryptomator_macos_autostart_MacLaunchServices_00024Native_disableLoginItem(JNIEnv *env, jobject thisObj) {
102-
if (@available(macOS 13, *)) {
103-
NSError* error = nil;
104-
if (![[SMAppService mainAppService] unregisterAndReturnError: & error]) {
105-
NSLog(@"Failed to remove login item: %@", error.localizedDescription);
106-
return NO;
107-
} else {
108-
return YES;
109-
}
110-
} else { // macOS < 13
111-
LSSharedFileListRef sharedFileList = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
112-
NSString *applicationPath = NSBundle.mainBundle.bundlePath;
113-
if (sharedFileList) {
114-
UInt32 seedValue;
115-
NSArray *sharedFileListArray = CFBridgingRelease(LSSharedFileListCopySnapshot(sharedFileList, &seedValue));
116-
for (id sharedFile in sharedFileListArray) {
117-
LSSharedFileListItemRef sharedFileListItem = (__bridge LSSharedFileListItemRef)sharedFile;
118-
CFURLRef applicationPathURL;
119-
if (LSSharedFileListItemResolve(sharedFileListItem, 0, &applicationPathURL, NULL) == noErr) {
120-
NSString *resolvedApplicationPath = [(__bridge NSURL *)applicationPathURL path];
121-
if ([resolvedApplicationPath compare:applicationPath] == NSOrderedSame) {
122-
LSSharedFileListItemRemove(sharedFileList, sharedFileListItem);
123-
}
124-
CFRelease(applicationPathURL);
125-
}
126-
}
127-
CFRelease(sharedFileList);
128-
return YES;
129-
} else {
130-
NSLog(@"Unable to create the shared file list.");
131-
return NO;
132-
}
133-
}
21+
return [SKYLaunchService disableLoginItem];
13422
}

0 commit comments

Comments
 (0)