-
-
Notifications
You must be signed in to change notification settings - Fork 228
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Detect and handle app swiching (unstable)
- Loading branch information
1 parent
a374350
commit 729db4d
Showing
10 changed files
with
184 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
@import UIKit; | ||
#import "LCUtils.h" | ||
#import "UIKitPrivate.h" | ||
|
||
extern NSUserDefaults *lcUserDefaults; | ||
|
||
@implementation LCSharedUtils | ||
+ (NSString *)certificatePassword { | ||
return [lcUserDefaults objectForKey:@"LCCertificatePassword"]; | ||
} | ||
|
||
+ (BOOL)launchToGuestApp { | ||
NSString *urlScheme; | ||
NSString *tsPath = [NSString stringWithFormat:@"%@/../_TrollStore", NSBundle.mainBundle.bundlePath]; | ||
int tries = 1; | ||
if (!access(tsPath.UTF8String, F_OK)) { | ||
urlScheme = @"apple-magnifier://enable-jit?bundle-id=%@"; | ||
} else if (self.certificatePassword) { | ||
tries = 8; | ||
urlScheme = @"livecontainer://livecontainer-relaunch"; | ||
} else { | ||
urlScheme = @"sidestore://sidejit-enable?bid=%@"; | ||
} | ||
NSURL *launchURL = [NSURL URLWithString:[NSString stringWithFormat:urlScheme, NSBundle.mainBundle.bundleIdentifier]]; | ||
if ([UIApplication.sharedApplication canOpenURL:launchURL]) { | ||
//[UIApplication.sharedApplication suspend]; | ||
for (int i = 0; i < tries; i++) { | ||
[UIApplication.sharedApplication openURL:launchURL options:@{} completionHandler:^(BOOL b) { | ||
exit(0); | ||
}]; | ||
} | ||
return YES; | ||
} | ||
return NO; | ||
} | ||
|
||
+ (BOOL)launchToGuestAppWithURL:(NSURL *)url { | ||
NSURLComponents* components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; | ||
if(![components.host isEqualToString:@"livecontainer-launch"]) return NO; | ||
|
||
for (NSURLQueryItem* queryItem in components.queryItems) { | ||
if ([queryItem.name isEqualToString:@"bundle-name"]) { | ||
[lcUserDefaults setObject:queryItem.value forKey:@"selected"]; | ||
|
||
// Attempt to restart LiveContainer with the selected guest app | ||
return [self launchToGuestApp]; | ||
break; | ||
} | ||
} | ||
return NO; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
@import ObjectiveC; | ||
@import UIKit; | ||
#import "LCUtils.h" | ||
#import "UIKitPrivate.h" | ||
|
||
static void swizzle(Class class, SEL originalAction, SEL swizzledAction) { | ||
method_exchangeImplementations(class_getInstanceMethod(class, originalAction), class_getInstanceMethod(class, swizzledAction)); | ||
} | ||
|
||
void UIKitGuestHooksInit() { | ||
swizzle(UIApplication.class, @selector(_applicationOpenURLAction:payload:origin:), @selector(hook__applicationOpenURLAction:payload:origin:)); | ||
swizzle(UIScene.class, @selector(scene:didReceiveActions:fromTransitionContext:), @selector(hook_scene:didReceiveActions:fromTransitionContext:)); | ||
} | ||
|
||
void LCShowSwitchAppConfirmation(NSURL *url) { | ||
NSString *message = [NSString stringWithFormat:@"%@\nAre you sure you want to switch app? Doing so will terminate this app.", url]; | ||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"LiveContainer" message:message preferredStyle:UIAlertControllerStyleAlert]; | ||
UIAlertAction* okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { | ||
[LCSharedUtils launchToGuestAppWithURL:url]; | ||
}]; | ||
[alert addAction:okAction]; | ||
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; | ||
[alert addAction:cancelAction]; | ||
UIWindow *window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; | ||
window.rootViewController = [UIViewController new]; | ||
window.windowLevel = UIApplication.sharedApplication.windows.lastObject.windowLevel + 1; | ||
window.windowScene = (id)UIApplication.sharedApplication.connectedScenes.anyObject; | ||
[window makeKeyAndVisible]; | ||
[window.rootViewController presentViewController:alert animated:YES completion:nil]; | ||
objc_setAssociatedObject(alert, @"window", window, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | ||
} | ||
|
||
// Handler for AppDelegate | ||
@implementation UIApplication(LiveContainerHook) | ||
- (void)hook__applicationOpenURLAction:(id)action payload:(NSDictionary *)payload origin:(id)origin { | ||
NSString *url = payload[UIApplicationLaunchOptionsURLKey]; | ||
if ([url hasPrefix:@"livecontainer://livecontainer-relaunch"]) { | ||
// Ignore | ||
return; | ||
} else if (![url hasPrefix:@"livecontainer://livecontainer-launch?"]) { | ||
// Not what we're looking for, pass it | ||
[self hook__applicationOpenURLAction:action payload:payload origin:origin]; | ||
return; | ||
} else if (![url hasSuffix:NSBundle.mainBundle.bundlePath.lastPathComponent]) { | ||
LCShowSwitchAppConfirmation([NSURL URLWithString:url]); | ||
} | ||
} | ||
@end | ||
|
||
// Handler for SceneDelegate | ||
@implementation UIScene(LiveContainerHook) | ||
- (void)hook_scene:(id)scene didReceiveActions:(NSSet *)actions fromTransitionContext:(id)context { | ||
UIOpenURLAction *urlAction; | ||
for (id obj in actions.allObjects) { | ||
if ([obj isKindOfClass:UIOpenURLAction.class]) { | ||
urlAction = obj; | ||
break; | ||
} | ||
} | ||
NSString *url = urlAction.url.absoluteString; | ||
// !urlAction || | ||
if ([url hasPrefix:@"livecontainer://livecontainer-relaunch"]) { | ||
// Ignore | ||
} else if (![url hasPrefix:@"livecontainer://livecontainer-launch?"]) { | ||
// Not what we're looking for, pass it | ||
[self hook_scene:scene didReceiveActions:actions fromTransitionContext:context]; | ||
return; | ||
} else if (![url hasSuffix:NSBundle.mainBundle.bundlePath.lastPathComponent]) { | ||
LCShowSwitchAppConfirmation(urlAction.url); | ||
} | ||
|
||
NSMutableSet *newActions = actions.mutableCopy; | ||
[newActions removeObject:urlAction]; | ||
[self hook_scene:scene didReceiveActions:newActions fromTransitionContext:context]; | ||
} | ||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters