Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…hanhduytran0#200 by @khanhduytran0, separate lc app settings from info.plist, add ignore dlopen error, fix black screen option
  • Loading branch information
hugeBlack committed Dec 28, 2024
1 parent 0ac2312 commit 6b0d913
Show file tree
Hide file tree
Showing 20 changed files with 309 additions and 99 deletions.
10 changes: 10 additions & 0 deletions FoundationPrivate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <Foundation/Foundation.h>

@interface NSBundle(private)
- (id)_cfBundle;
@end

@interface NSUserDefaults(private)
+ (void)setStandardUserDefaults:(id)defaults;
- (NSString*)_identifier;
@end
13 changes: 8 additions & 5 deletions LCSharedUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,12 @@ + (BOOL)launchToGuestApp {
urlScheme = @"sidestore://sidejit-enable?bid=%@";
}
NSURL *launchURL = [NSURL URLWithString:[NSString stringWithFormat:urlScheme, NSBundle.mainBundle.bundleIdentifier]];
if ([UIApplication.sharedApplication canOpenURL:launchURL]) {

UIApplication *application = [NSClassFromString(@"UIApplication") sharedApplication];
if ([application canOpenURL:launchURL]) {
//[UIApplication.sharedApplication suspend];
for (int i = 0; i < tries; i++) {
[UIApplication.sharedApplication openURL:launchURL options:@{} completionHandler:^(BOOL b) {
[application openURL:launchURL options:@{} completionHandler:^(BOOL b) {
exit(0);
}];
}
Expand All @@ -88,8 +90,9 @@ + (BOOL)askForJIT {
if (!access(tsPath.UTF8String, F_OK)) {
urlScheme = @"apple-magnifier://enable-jit?bundle-id=%@";
NSURL *launchURL = [NSURL URLWithString:[NSString stringWithFormat:urlScheme, NSBundle.mainBundle.bundleIdentifier]];
if ([UIApplication.sharedApplication canOpenURL:launchURL]) {
[UIApplication.sharedApplication openURL:launchURL options:@{} completionHandler:nil];
UIApplication *application = [NSClassFromString(@"UIApplication") sharedApplication];
if ([application canOpenURL:launchURL]) {
[application openURL:launchURL options:@{} completionHandler:nil];
[LCSharedUtils launchToGuestApp];
return YES;
}
Expand Down Expand Up @@ -346,7 +349,7 @@ + (NSString*)findDefaultContainerWithBundleId:(NSString*)bundleId {
// find app's default container
NSURL* appGroupFolder = [[LCSharedUtils appGroupPath] URLByAppendingPathComponent:@"LiveContainer"];

NSString* bundleInfoPath = [NSString stringWithFormat:@"%@/Applications/%@/Info.plist", appGroupFolder.path, bundleId];
NSString* bundleInfoPath = [NSString stringWithFormat:@"%@/Applications/%@/LCAppInfo.plist", appGroupFolder.path, bundleId];
NSDictionary* infoDict = [NSDictionary dictionaryWithContentsOfFile:bundleInfoPath];
return infoDict[@"LCDataUUID"];
}
Expand Down
7 changes: 5 additions & 2 deletions LiveContainerSwiftUI/LCAppInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ typedef NS_ENUM(NSInteger, LCOrientationLock){
};

@interface LCAppInfo : NSObject {
NSMutableDictionary* _info;
NSString* _bundlePath;
NSMutableDictionary* _info;
NSMutableDictionary* _infoPlist;
NSString* _bundlePath;
}
@property NSString* relativeBundlePath;
@property bool isShared;
@property bool isJITNeeded;
@property bool isLocked;
@property bool isHidden;
@property bool doSymlinkInbox;
@property bool ignoreDlopenError;
@property bool fixBlackScreen;
@property bool bypassAssertBarrierOnQueue;
@property UIColor* cachedColor;
@property Signer signer;
Expand Down
129 changes: 98 additions & 31 deletions LiveContainerSwiftUI/LCAppInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,46 @@ - (instancetype)initWithBundlePath:(NSString*)bundlePath {
self.isShared = false;
if(self) {
_bundlePath = bundlePath;
_info = [NSMutableDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", bundlePath]];
_infoPlist = [NSMutableDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", bundlePath]];
_info = [NSMutableDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/LCAppInfo.plist", bundlePath]];
if(!_info) {
_info = [[NSMutableDictionary alloc] init];
}
if(!_infoPlist) {
_infoPlist = [[NSMutableDictionary alloc] init];
}

// migrate old appInfo
if(_infoPlist[@"LCPatchRevision"]) {
NSArray* lcAppInfoKeys = @[
@"LCPatchRevision",
@"LCOrignalBundleIdentifier",
@"LCDataUUID",
@"LCTweakFolder",
@"LCJITLessSignID",
@"LCSelectedLanguage",
@"LCExpirationDate",
@"LCTeamId",
@"isJITNeeded",
@"isLocked",
@"isHidden",
@"doUseLCBundleId",
@"doSymlinkInbox",
@"bypassAssertBarrierOnQueue",
@"signer",
@"LCOrientationLock",
@"cachedColor",
@"LCContainers",
@"ignoreDlopenError"
];
for(NSString* key in lcAppInfoKeys) {
_info[key] = _infoPlist[key];
[_infoPlist removeObjectForKey:key];
}
[_infoPlist writeToFile:[NSString stringWithFormat:@"%@/Info.plist", bundlePath] atomically:YES];
[self save];
}

_autoSaveDisabled = false;
}
return self;
Expand All @@ -25,8 +64,8 @@ - (NSMutableArray*)urlSchemes {
// find all url schemes
NSMutableArray* urlSchemes = [[NSMutableArray alloc] init];
int nowSchemeCount = 0;
if (_info[@"CFBundleURLTypes"]) {
NSMutableArray* urlTypes = _info[@"CFBundleURLTypes"];
if (_infoPlist[@"CFBundleURLTypes"]) {
NSMutableArray* urlTypes = _infoPlist[@"CFBundleURLTypes"];

for(int i = 0; i < [urlTypes count]; ++i) {
NSMutableDictionary* nowUrlType = [urlTypes objectAtIndex:i];
Expand All @@ -45,21 +84,21 @@ - (NSMutableArray*)urlSchemes {
}

- (NSString*)displayName {
if (_info[@"CFBundleDisplayName"]) {
return _info[@"CFBundleDisplayName"];
} else if (_info[@"CFBundleName"]) {
return _info[@"CFBundleName"];
} else if (_info[@"CFBundleExecutable"]) {
return _info[@"CFBundleExecutable"];
if (_infoPlist[@"CFBundleDisplayName"]) {
return _infoPlist[@"CFBundleDisplayName"];
} else if (_infoPlist[@"CFBundleName"]) {
return _infoPlist[@"CFBundleName"];
} else if (_infoPlist[@"CFBundleExecutable"]) {
return _infoPlist[@"CFBundleExecutable"];
} else {
return nil;
return @"Unknown";
}
}

- (NSString*)version {
NSString* version = _info[@"CFBundleShortVersionString"];
NSString* version = _infoPlist[@"CFBundleShortVersionString"];
if (!version) {
version = _info[@"CFBundleVersion"];
version = _infoPlist[@"CFBundleVersion"];
}
return version;
}
Expand All @@ -68,7 +107,7 @@ - (NSString*)bundleIdentifier {
if([self doUseLCBundleId]) {
return _info[@"LCOrignalBundleIdentifier"];
} else {
return _info[@"CFBundleIdentifier"];
return _infoPlist[@"CFBundleIdentifier"];
}
}

Expand Down Expand Up @@ -113,13 +152,13 @@ - (NSMutableDictionary*)info {
}

- (UIImage*)icon {
UIImage* icon = [UIImage imageNamed:[_info valueForKeyPath:@"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles"][0] inBundle:[[NSBundle alloc] initWithPath: _bundlePath] compatibleWithTraitCollection:nil];
UIImage* icon = [UIImage imageNamed:[_infoPlist valueForKeyPath:@"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles"][0] inBundle:[[NSBundle alloc] initWithPath: _bundlePath] compatibleWithTraitCollection:nil];
if(!icon) {
icon = [UIImage imageNamed:[_info valueForKeyPath:@"CFBundleIconFiles"][0] inBundle:[[NSBundle alloc] initWithPath: _bundlePath] compatibleWithTraitCollection:nil];
icon = [UIImage imageNamed:[_infoPlist valueForKeyPath:@"CFBundleIconFiles"][0] inBundle:[[NSBundle alloc] initWithPath: _bundlePath] compatibleWithTraitCollection:nil];
}

if(!icon) {
icon = [UIImage imageNamed:[_info valueForKeyPath:@"CFBundleIcons~ipad"][@"CFBundlePrimaryIcon"][@"CFBundleIconName"] inBundle:[[NSBundle alloc] initWithPath: _bundlePath] compatibleWithTraitCollection:nil];
icon = [UIImage imageNamed:[_infoPlist valueForKeyPath:@"CFBundleIcons~ipad"][@"CFBundlePrimaryIcon"][@"CFBundleIconName"] inBundle:[[NSBundle alloc] initWithPath: _bundlePath] compatibleWithTraitCollection:nil];
}

if(!icon) {
Expand Down Expand Up @@ -188,7 +227,7 @@ - (NSDictionary *)generateWebClipConfigWithContainerId:(NSString*)containerId {

- (void)save {
if(!_autoSaveDisabled) {
[_info writeToFile:[NSString stringWithFormat:@"%@/Info.plist", _bundlePath] atomically:YES];
[_info writeToFile:[NSString stringWithFormat:@"%@/LCAppInfo.plist", _bundlePath] atomically:YES];
}

}
Expand All @@ -212,6 +251,7 @@ - (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(bool success, NSStr
NSString *appPath = self.bundlePath;
NSString *infoPath = [NSString stringWithFormat:@"%@/Info.plist", appPath];
NSMutableDictionary *info = _info;
NSMutableDictionary *infoPlist = _infoPlist;
if (!info) {
completetionHandler(NO, @"Info.plist not found");
return;
Expand All @@ -220,7 +260,7 @@ - (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(bool success, NSStr
// Update patch
int currentPatchRev = 5;
if ([info[@"LCPatchRevision"] intValue] < currentPatchRev) {
NSString *execPath = [NSString stringWithFormat:@"%@/%@", appPath, info[@"CFBundleExecutable"]];
NSString *execPath = [NSString stringWithFormat:@"%@/%@", appPath, _infoPlist[@"CFBundleExecutable"]];
NSString *error = LCParseMachO(execPath.UTF8String, ^(const char *path, struct mach_header_64 *header) {
LCPatchExecSlice(path, header);
});
Expand Down Expand Up @@ -270,16 +310,16 @@ - (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(bool success, NSStr
// Don't let main executable get entitlements
[NSFileManager.defaultManager copyItemAtPath:NSBundle.mainBundle.executablePath toPath:tmpExecPath error:nil];

info[@"LCBundleExecutable"] = info[@"CFBundleExecutable"];
info[@"LCBundleIdentifier"] = info[@"CFBundleIdentifier"];
info[@"CFBundleExecutable"] = tmpExecPath.lastPathComponent;
info[@"CFBundleIdentifier"] = NSBundle.mainBundle.bundleIdentifier;
[info writeToFile:infoPath atomically:YES];
infoPlist[@"LCBundleExecutable"] = infoPlist[@"CFBundleExecutable"];
infoPlist[@"LCBundleIdentifier"] = infoPlist[@"CFBundleIdentifier"];
infoPlist[@"CFBundleExecutable"] = tmpExecPath.lastPathComponent;
infoPlist[@"CFBundleIdentifier"] = NSBundle.mainBundle.bundleIdentifier;
[infoPlist writeToFile:infoPath atomically:YES];
}
info[@"CFBundleExecutable"] = info[@"LCBundleExecutable"];
info[@"CFBundleIdentifier"] = info[@"LCBundleIdentifier"];
[info removeObjectForKey:@"LCBundleExecutable"];
[info removeObjectForKey:@"LCBundleIdentifier"];
infoPlist[@"CFBundleExecutable"] = infoPlist[@"LCBundleExecutable"];
infoPlist[@"CFBundleIdentifier"] = infoPlist[@"LCBundleIdentifier"];
[infoPlist removeObjectForKey:@"LCBundleExecutable"];
[infoPlist removeObjectForKey:@"LCBundleIdentifier"];

void (^signCompletionHandler)(BOOL success, NSDate* expirationDate, NSString* teamId, NSError *error) = ^(BOOL success, NSDate* expirationDate, NSString* teamId, NSError *_Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
Expand All @@ -299,7 +339,7 @@ - (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(bool success, NSStr
}
// Save sign ID and restore bundle ID
[self save];

[infoPlist writeToFile:infoPath atomically:YES];
completetionHandler(success, error.localizedDescription);

});
Expand Down Expand Up @@ -384,6 +424,31 @@ - (void)setDoSymlinkInbox:(bool)doSymlinkInbox {

}

- (bool)ignoreDlopenError {
if(_info[@"ignoreDlopenError"] != nil) {
return [_info[@"ignoreDlopenError"] boolValue];
} else {
return NO;
}
}
- (void)setIgnoreDlopenError:(bool)ignoreDlopenError {
_info[@"ignoreDlopenError"] = [NSNumber numberWithBool:ignoreDlopenError];
[self save];
}

- (bool)fixBlackScreen {
if(_info[@"fixBlackScreen"] != nil) {
return [_info[@"fixBlackScreen"] boolValue];
} else {
return NO;
}
}
- (void)setFixBlackScreen:(bool)fixBlackScreen {
_info[@"fixBlackScreen"] = [NSNumber numberWithBool:fixBlackScreen];
[self save];
}


- (bool)doUseLCBundleId {
if(_info[@"doUseLCBundleId"] != nil) {
return [_info[@"doUseLCBundleId"] boolValue];
Expand All @@ -393,13 +458,15 @@ - (bool)doUseLCBundleId {
}
- (void)setDoUseLCBundleId:(bool)doUseLCBundleId {
_info[@"doUseLCBundleId"] = [NSNumber numberWithBool:doUseLCBundleId];
NSString *infoPath = [NSString stringWithFormat:@"%@/Info.plist", self.bundlePath];
if(doUseLCBundleId) {
_info[@"LCOrignalBundleIdentifier"] = _info[@"CFBundleIdentifier"];
_info[@"CFBundleIdentifier"] = NSBundle.mainBundle.bundleIdentifier;
_info[@"LCOrignalBundleIdentifier"] = _infoPlist[@"CFBundleIdentifier"];
_infoPlist[@"CFBundleIdentifier"] = NSBundle.mainBundle.bundleIdentifier;
} else if (_info[@"LCOrignalBundleIdentifier"]) {
_info[@"CFBundleIdentifier"] = _info[@"LCOrignalBundleIdentifier"];
_infoPlist[@"CFBundleIdentifier"] = _info[@"LCOrignalBundleIdentifier"];
[_info removeObjectForKey:@"LCOrignalBundleIdentifier"];
}
[_infoPlist writeToFile:infoPath atomically:YES];
[self save];
}

Expand Down
1 change: 1 addition & 0 deletions LiveContainerSwiftUI/LCAppListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
finalNewApp.selectedLanguage = appToReplace.appInfo.selectedLanguage
finalNewApp.dataUUID = appToReplace.appInfo.dataUUID
finalNewApp.orientationLock = appToReplace.appInfo.orientationLock
finalNewApp.ignoreDlopenError = appToReplace.appInfo.ignoreDlopenError
finalNewApp.autoSaveDisabled = false
finalNewApp.save()
}
Expand Down
4 changes: 4 additions & 0 deletions LiveContainerSwiftUI/LCAppModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class LCAppModel: ObservableObject, Hashable {
@Published var uiUseLCBundleId : Bool
@Published var uiBypassAssertBarrierOnQueue : Bool
@Published var uiSigner : Signer
@Published var uiIgnoreDlopenError : Bool
@Published var uiFixBlackScreen : Bool
@Published var uiOrientationLock : LCOrientationLock
@Published var uiSelectedLanguage : String
@Published var supportedLanaguages : [String]?
Expand Down Expand Up @@ -55,6 +57,8 @@ class LCAppModel: ObservableObject, Hashable {
self.uiSigner = appInfo.signer
self.uiOrientationLock = appInfo.orientationLock
self.uiUseLCBundleId = appInfo.doUseLCBundleId
self.uiIgnoreDlopenError = appInfo.ignoreDlopenError
self.uiFixBlackScreen = appInfo.fixBlackScreen

for container in uiContainers {
if container.folderName == uiDefaultDataFolder {
Expand Down
32 changes: 32 additions & 0 deletions LiveContainerSwiftUI/LCAppSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,28 @@ struct LCAppSettingsView : View{
})
}
}

Section {
Toggle(isOn: $model.uiIgnoreDlopenError) {
Text("lc.appSettings.ignoreDlopenError".loc)
}
.onChange(of: model.uiIgnoreDlopenError, perform: { newValue in
Task { await setIgnoreDlopenError(newValue) }
})
} footer: {
Text("lc.appSettings.ignoreDlopenErrorDesc".loc)
}

Section {
Toggle(isOn: $model.uiFixBlackScreen) {
Text("lc.appSettings.fixBlackScreen".loc)
}
.onChange(of: model.uiFixBlackScreen, perform: { newValue in
Task { await setFixBlackScreen(newValue) }
})
} footer: {
Text("lc.appSettings.fixBlackScreenDesc".loc)
}


Section {
Expand Down Expand Up @@ -492,6 +514,16 @@ struct LCAppSettingsView : View{
model.uiUseLCBundleId = doUseLCBundleId
}

func setIgnoreDlopenError(_ ignoreDlopenError : Bool) async {
appInfo.ignoreDlopenError = ignoreDlopenError
model.uiIgnoreDlopenError = ignoreDlopenError
}

func setFixBlackScreen(_ fixBlackScreen : Bool) async {
appInfo.fixBlackScreen = fixBlackScreen
model.uiFixBlackScreen = fixBlackScreen
}

func setOrientationLock(_ lock : LCOrientationLock) async {
appInfo.orientationLock = lock
model.uiOrientationLock = lock
Expand Down
Loading

0 comments on commit 6b0d913

Please sign in to comment.