mirror of
https://github.com/opa334/TrollStore.git
synced 2025-02-20 20:25:42 +08:00
Compare commits
No commits in common. "783ab43c3e7fd4cd9a2d265c8ebc56922cdf7e00" and "b136e3a29274a81ae698396a9ce61f9aaec67f03" have entirely different histories.
783ab43c3e
...
b136e3a292
@ -14,6 +14,6 @@ trollstorehelper_CODESIGN_FLAGS = --entitlements entitlements.plist
|
|||||||
trollstorehelper_INSTALL_PATH = /usr/local/bin
|
trollstorehelper_INSTALL_PATH = /usr/local/bin
|
||||||
trollstorehelper_LIBRARIES = archive
|
trollstorehelper_LIBRARIES = archive
|
||||||
trollstorehelper_FRAMEWORKS = CoreTelephony
|
trollstorehelper_FRAMEWORKS = CoreTelephony
|
||||||
trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager FrontBoardServices
|
trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager
|
||||||
|
|
||||||
include $(THEOS_MAKE_PATH)/tool.mk
|
include $(THEOS_MAKE_PATH)/tool.mk
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
BOOL checkDeveloperMode(void);
|
|
||||||
BOOL armDeveloperMode(BOOL* alreadyEnabled);
|
|
@ -1,142 +0,0 @@
|
|||||||
@import Foundation;
|
|
||||||
|
|
||||||
// Types
|
|
||||||
typedef NSObject* xpc_object_t;
|
|
||||||
typedef xpc_object_t xpc_connection_t;
|
|
||||||
typedef void (^xpc_handler_t)(xpc_object_t object);
|
|
||||||
|
|
||||||
// Serialization
|
|
||||||
extern CFTypeRef _CFXPCCreateCFObjectFromXPCObject(xpc_object_t xpcattrs);
|
|
||||||
extern xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef attrs);
|
|
||||||
extern xpc_object_t _CFXPCCreateXPCMessageWithCFObject(CFTypeRef obj);
|
|
||||||
extern CFTypeRef _CFXPCCreateCFObjectFromXPCMessage(xpc_object_t obj);
|
|
||||||
|
|
||||||
// Communication
|
|
||||||
extern xpc_connection_t xpc_connection_create_mach_service(const char* name, dispatch_queue_t targetq, uint64_t flags);
|
|
||||||
extern void xpc_connection_set_event_handler(xpc_connection_t connection, xpc_handler_t handler);
|
|
||||||
extern void xpc_connection_resume(xpc_connection_t connection);
|
|
||||||
extern void xpc_connection_send_message_with_reply(xpc_connection_t connection, xpc_object_t message, dispatch_queue_t replyq, xpc_handler_t handler);
|
|
||||||
extern xpc_object_t xpc_connection_send_message_with_reply_sync(xpc_connection_t connection, xpc_object_t message);
|
|
||||||
extern xpc_object_t xpc_dictionary_get_value(xpc_object_t xdict, const char *key);
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
kAMFIActionArm = 0, // Trigger a prompt asking the user to enable developer mode on the next reboot
|
|
||||||
// (regardless of current state)
|
|
||||||
kAMFIActionDisable = 1, // Disable developer mode if it's currently enabled. Takes effect immediately.
|
|
||||||
kAMFIActionStatus = 2, // Returns a dict: {success: bool, status: bool, armed: bool}
|
|
||||||
} AMFIXPCAction;
|
|
||||||
|
|
||||||
xpc_connection_t startConnection(void) {
|
|
||||||
xpc_connection_t connection = xpc_connection_create_mach_service("com.apple.amfi.xpc", NULL, 0);
|
|
||||||
if (!connection) {
|
|
||||||
NSLog(@"[startXPCConnection] Failed to create XPC connection to amfid");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
|
|
||||||
});
|
|
||||||
xpc_connection_resume(connection);
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSDictionary* sendXPCRequest(xpc_connection_t connection, AMFIXPCAction action) {
|
|
||||||
xpc_object_t message = _CFXPCCreateXPCMessageWithCFObject((__bridge CFDictionaryRef) @{@"action": @(action)});
|
|
||||||
xpc_object_t replyMsg = xpc_connection_send_message_with_reply_sync(connection, message);
|
|
||||||
if (!replyMsg) {
|
|
||||||
NSLog(@"[sendXPCRequest] got no reply from amfid");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
xpc_object_t replyObj = xpc_dictionary_get_value(replyMsg, "cfreply");
|
|
||||||
if (!replyObj) {
|
|
||||||
NSLog(@"[sendXPCRequest] got reply but no cfreply");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSDictionary* asCF = (__bridge NSDictionary*)_CFXPCCreateCFObjectFromXPCMessage(replyObj);
|
|
||||||
return asCF;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL getDeveloperModeState(xpc_connection_t connection) {
|
|
||||||
NSDictionary* reply = sendXPCRequest(connection, kAMFIActionStatus);
|
|
||||||
if (!reply) {
|
|
||||||
NSLog(@"[getDeveloperModeState] failed to get reply");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSLog(@"[getDeveloperModeState] got reply %@", reply);
|
|
||||||
|
|
||||||
NSObject* success = reply[@"success"];
|
|
||||||
if (!success || ![success isKindOfClass:[NSNumber class]] || ![(NSNumber*)success boolValue]) {
|
|
||||||
NSLog(@"[getDeveloperModeState] request failed with error %@", reply[@"error"]);
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSObject* status = reply[@"status"];
|
|
||||||
if (!status || ![status isKindOfClass:[NSNumber class]]) {
|
|
||||||
NSLog(@"[getDeveloperModeState] request succeeded but no status");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [(NSNumber*)status boolValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL setDeveloperModeState(xpc_connection_t connection, BOOL enable) {
|
|
||||||
NSDictionary* reply = sendXPCRequest(connection, enable ? kAMFIActionArm : kAMFIActionDisable);
|
|
||||||
if (!reply) {
|
|
||||||
NSLog(@"[setDeveloperModeState] failed to get reply");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSObject* success = reply[@"success"];
|
|
||||||
if (!success || ![success isKindOfClass:[NSNumber class]] || ![(NSNumber*)success boolValue]) {
|
|
||||||
NSLog(@"[setDeveloperModeState] request failed with error %@", reply[@"error"]);
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL checkDeveloperMode(void) {
|
|
||||||
// Developer mode does not exist before iOS 16
|
|
||||||
if (@available(iOS 16, *)) {
|
|
||||||
xpc_connection_t connection = startConnection();
|
|
||||||
if (!connection) {
|
|
||||||
NSLog(@"[checkDeveloperMode] failed to start connection");
|
|
||||||
// Assume it's disabled
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getDeveloperModeState(connection);
|
|
||||||
} else {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL armDeveloperMode(BOOL* alreadyEnabled) {
|
|
||||||
// Developer mode does not exist before iOS 16
|
|
||||||
if (@available(iOS 16, *)) {
|
|
||||||
xpc_connection_t connection = startConnection();
|
|
||||||
if (!connection) {
|
|
||||||
NSLog(@"[armDeveloperMode] failed to start connection");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL enabled = getDeveloperModeState(connection);
|
|
||||||
if (alreadyEnabled) {
|
|
||||||
*alreadyEnabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enabled) {
|
|
||||||
// NSLog(@"[armDeveloperMode] already enabled");
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL success = setDeveloperModeState(connection, YES);
|
|
||||||
if (!success) {
|
|
||||||
NSLog(@"[armDeveloperMode] failed to arm");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
@ -44,9 +44,5 @@
|
|||||||
<string>Uninstall</string>
|
<string>Uninstall</string>
|
||||||
<string>UpdatePlaceholderMetadata</string>
|
<string>UpdatePlaceholderMetadata</string>
|
||||||
</array>
|
</array>
|
||||||
<key>com.apple.private.amfi.developer-mode-control</key>
|
|
||||||
<true/>
|
|
||||||
<key>com.apple.frontboard.shutdown</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#import <sys/utsname.h>
|
#import <sys/utsname.h>
|
||||||
#import <mach-o/loader.h>
|
#import <mach-o/loader.h>
|
||||||
#import <mach-o/fat.h>
|
#import <mach-o/fat.h>
|
||||||
#import "devmode.h"
|
|
||||||
#ifndef EMBEDDED_ROOT_HELPER
|
#ifndef EMBEDDED_ROOT_HELPER
|
||||||
#import "codesign.h"
|
#import "codesign.h"
|
||||||
#import "coretrust_bug.h"
|
#import "coretrust_bug.h"
|
||||||
@ -21,7 +20,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#import <SpringBoardServices/SpringBoardServices.h>
|
#import <SpringBoardServices/SpringBoardServices.h>
|
||||||
#import <FrontBoardServices/FBSSystemService.h>
|
|
||||||
#import <Security/Security.h>
|
#import <Security/Security.h>
|
||||||
|
|
||||||
#ifdef EMBEDDED_ROOT_HELPER
|
#ifdef EMBEDDED_ROOT_HELPER
|
||||||
@ -566,10 +564,6 @@ int signApp(NSString* appPath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On iOS 16+, binaries with certain entitlements requires developer mode to be enabled, so we'll check
|
|
||||||
// while we're fixing entitlements
|
|
||||||
BOOL requiresDevMode = NO;
|
|
||||||
|
|
||||||
NSURL* fileURL;
|
NSURL* fileURL;
|
||||||
NSDirectoryEnumerator *enumerator;
|
NSDirectoryEnumerator *enumerator;
|
||||||
|
|
||||||
@ -614,25 +608,6 @@ int signApp(NSString* appPath)
|
|||||||
|
|
||||||
if (!entitlementsToUse) entitlementsToUse = [NSMutableDictionary new];
|
if (!entitlementsToUse) entitlementsToUse = [NSMutableDictionary new];
|
||||||
|
|
||||||
// Developer mode does not exist before iOS 16
|
|
||||||
if (@available(iOS 16, *)){
|
|
||||||
if (!requiresDevMode) {
|
|
||||||
for (NSString* restrictedEntitlementKey in @[
|
|
||||||
@"get-task-allow",
|
|
||||||
@"task_for_pid-allow",
|
|
||||||
@"com.apple.system-task-ports",
|
|
||||||
@"com.apple.system-task-ports.control",
|
|
||||||
@"com.apple.system-task-ports.token.control",
|
|
||||||
@"com.apple.private.cs.debugger"
|
|
||||||
]) {
|
|
||||||
NSObject *restrictedEntitlement = entitlementsToUse[restrictedEntitlementKey];
|
|
||||||
if (restrictedEntitlement && [restrictedEntitlement isKindOfClass:[NSNumber class]] && [(NSNumber *)restrictedEntitlement boolValue]) {
|
|
||||||
requiresDevMode = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NSObject *containerRequiredO = entitlementsToUse[@"com.apple.private.security.container-required"];
|
NSObject *containerRequiredO = entitlementsToUse[@"com.apple.private.security.container-required"];
|
||||||
BOOL containerRequired = YES;
|
BOOL containerRequired = YES;
|
||||||
if (containerRequiredO && [containerRequiredO isKindOfClass:[NSNumber class]]) {
|
if (containerRequiredO && [containerRequiredO isKindOfClass:[NSNumber class]]) {
|
||||||
@ -711,11 +686,6 @@ int signApp(NSString* appPath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requiresDevMode) {
|
|
||||||
// Postpone trying to enable dev mode until after the app is (successfully) installed
|
|
||||||
return 182;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -800,19 +770,10 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate,
|
|||||||
applyPatchesToInfoDictionary(appBundleToInstallPath);
|
applyPatchesToInfoDictionary(appBundleToInstallPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL requiresDevMode = NO;
|
|
||||||
|
|
||||||
if(sign)
|
if(sign)
|
||||||
{
|
{
|
||||||
int signRet = signApp(appBundleToInstallPath);
|
int signRet = signApp(appBundleToInstallPath);
|
||||||
// 182: app requires developer mode; non-fatal
|
if(signRet != 0) return signRet;
|
||||||
if(signRet != 0) {
|
|
||||||
if (signRet == 182) {
|
|
||||||
requiresDevMode = YES;
|
|
||||||
} else {
|
|
||||||
return signRet;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MCMAppContainer* appContainer = [MCMAppContainer containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil];
|
MCMAppContainer* appContainer = [MCMAppContainer containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil];
|
||||||
@ -958,23 +919,6 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate,
|
|||||||
[[NSFileManager defaultManager] removeItemAtURL:appContainer.url error:nil];
|
[[NSFileManager defaultManager] removeItemAtURL:appContainer.url error:nil];
|
||||||
return 181;
|
return 181;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle developer mode after installing and registering the app, to ensure that we
|
|
||||||
// don't arm developer mode but then fail to install the app
|
|
||||||
if (requiresDevMode) {
|
|
||||||
BOOL alreadyEnabled = NO;
|
|
||||||
if (armDeveloperMode(&alreadyEnabled)) {
|
|
||||||
if (!alreadyEnabled) {
|
|
||||||
NSLog(@"[installApp] app requires developer mode and we have successfully armed it");
|
|
||||||
// non-fatal
|
|
||||||
return 182;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
NSLog(@"[installApp] failed to arm developer mode");
|
|
||||||
// fatal
|
|
||||||
return 183;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1526,22 +1470,6 @@ int MAIN_NAME(int argc, char *argv[], char *envp[])
|
|||||||
setTSURLSchemeState(newState, nil);
|
setTSURLSchemeState(newState, nil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if([cmd isEqualToString:@"check-dev-mode"])
|
|
||||||
{
|
|
||||||
// switch the result, so 0 is enabled, and 1 is disabled/error
|
|
||||||
ret = !checkDeveloperMode();
|
|
||||||
}
|
|
||||||
else if([cmd isEqualToString:@"arm-dev-mode"])
|
|
||||||
{
|
|
||||||
// assumes that checkDeveloperMode() has already been called
|
|
||||||
ret = !armDeveloperMode(NULL);
|
|
||||||
}
|
|
||||||
else if([cmd isEqualToString:@"reboot"])
|
|
||||||
{
|
|
||||||
[[FBSSystemService sharedService] reboot];
|
|
||||||
// Give the system some time to reboot
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
NSLog(@"trollstorehelper returning %d", ret);
|
NSLog(@"trollstorehelper returning %d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -34,7 +34,7 @@ ifeq ($(EMBEDDED_ROOT_HELPER),1)
|
|||||||
TrollStorePersistenceHelper_CFLAGS += -DEMBEDDED_ROOT_HELPER=1
|
TrollStorePersistenceHelper_CFLAGS += -DEMBEDDED_ROOT_HELPER=1
|
||||||
TrollStorePersistenceHelper_FILES += $(wildcard ../RootHelper/*.m)
|
TrollStorePersistenceHelper_FILES += $(wildcard ../RootHelper/*.m)
|
||||||
TrollStorePersistenceHelper_LIBRARIES += archive
|
TrollStorePersistenceHelper_LIBRARIES += archive
|
||||||
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS += SpringBoardServices BackBoardServices FrontBoardServices
|
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS += SpringBoardServices BackBoardServices
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(THEOS_MAKE_PATH)/application.mk
|
include $(THEOS_MAKE_PATH)/application.mk
|
@ -80,12 +80,6 @@ extern NSUserDefaults* trollStoreUserDefaults();
|
|||||||
case 181:
|
case 181:
|
||||||
errorDescription = @"Failed to add app to icon cache.";
|
errorDescription = @"Failed to add app to icon cache.";
|
||||||
break;
|
break;
|
||||||
case 182:
|
|
||||||
errorDescription = @"The app was installed successfully, but requires developer mode to be enabled to run. After rebooting, select \"Turn On\" to enable developer mode.";
|
|
||||||
break;
|
|
||||||
case 183:
|
|
||||||
errorDescription = @"Failed to enable developer mode.";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NSError* error = [NSError errorWithDomain:TrollStoreErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : errorDescription}];
|
NSError* error = [NSError errorWithDomain:TrollStoreErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : errorDescription}];
|
||||||
|
@ -32,58 +32,42 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
|||||||
{
|
{
|
||||||
[TSPresentationDelegate stopActivityWithCompletion:^
|
[TSPresentationDelegate stopActivityWithCompletion:^
|
||||||
{
|
{
|
||||||
if (ret == 0) {
|
if(ret != 0)
|
||||||
// success
|
{
|
||||||
if(completionBlock) completionBlock(YES, nil);
|
|
||||||
} else if (ret == 171) {
|
|
||||||
// recoverable error
|
|
||||||
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
|
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
|
||||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
|
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
|
||||||
{
|
{
|
||||||
if(completionBlock) completionBlock(NO, error);
|
if(ret == 171)
|
||||||
|
{
|
||||||
|
if(completionBlock) completionBlock(NO, error);
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
[errorAlert addAction:closeAction];
|
[errorAlert addAction:closeAction];
|
||||||
|
|
||||||
UIAlertAction* forceInstallAction = [UIAlertAction actionWithTitle:@"Force Installation" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
|
if(ret == 171)
|
||||||
{
|
{
|
||||||
[self handleAppInstallFromFile:pathToIPA forceInstall:YES completion:completionBlock];
|
UIAlertAction* forceInstallAction = [UIAlertAction actionWithTitle:@"Force Installation" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
|
||||||
}];
|
{
|
||||||
[errorAlert addAction:forceInstallAction];
|
[self handleAppInstallFromFile:pathToIPA forceInstall:YES completion:completionBlock];
|
||||||
|
}];
|
||||||
|
[errorAlert addAction:forceInstallAction];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UIAlertAction* copyLogAction = [UIAlertAction actionWithTitle:@"Copy Debug Log" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
|
||||||
|
{
|
||||||
|
UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
|
||||||
|
pasteboard.string = log;
|
||||||
|
}];
|
||||||
|
[errorAlert addAction:copyLogAction];
|
||||||
|
}
|
||||||
|
|
||||||
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
|
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
|
||||||
} else if (ret == 182) {
|
}
|
||||||
// non-fatal informative message
|
|
||||||
UIAlertController* rebootNotification = [UIAlertController alertControllerWithTitle:@"Reboot Required" message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
|
|
||||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action)
|
|
||||||
{
|
|
||||||
if(completionBlock) completionBlock(YES, nil);
|
|
||||||
}];
|
|
||||||
[rebootNotification addAction:closeAction];
|
|
||||||
|
|
||||||
UIAlertAction* rebootAction = [UIAlertAction actionWithTitle:@"Reboot Now" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
|
if(ret != 171)
|
||||||
{
|
{
|
||||||
if(completionBlock) completionBlock(YES, nil);
|
if(completionBlock) completionBlock((BOOL)error, error);
|
||||||
spawnRoot(rootHelperPath(), @[@"reboot"], nil, nil);
|
|
||||||
}];
|
|
||||||
[rebootNotification addAction:rebootAction];
|
|
||||||
|
|
||||||
[TSPresentationDelegate presentViewController:rebootNotification animated:YES completion:nil];
|
|
||||||
} else {
|
|
||||||
// unrecoverable error
|
|
||||||
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
|
|
||||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
|
|
||||||
[errorAlert addAction:closeAction];
|
|
||||||
|
|
||||||
UIAlertAction* copyLogAction = [UIAlertAction actionWithTitle:@"Copy Debug Log" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
|
|
||||||
{
|
|
||||||
UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
|
|
||||||
pasteboard.string = log;
|
|
||||||
}];
|
|
||||||
[errorAlert addAction:copyLogAction];
|
|
||||||
|
|
||||||
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
|
|
||||||
|
|
||||||
if(completionBlock) completionBlock(NO, error);
|
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
});
|
});
|
||||||
|
@ -5,6 +5,5 @@
|
|||||||
PSSpecifier* _installPersistenceHelperSpecifier;
|
PSSpecifier* _installPersistenceHelperSpecifier;
|
||||||
NSString* _newerVersion;
|
NSString* _newerVersion;
|
||||||
NSString* _newerLdidVersion;
|
NSString* _newerLdidVersion;
|
||||||
BOOL _devModeEnabled;
|
|
||||||
}
|
}
|
||||||
@end
|
@end
|
@ -55,16 +55,6 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (@available(iOS 16, *))
|
|
||||||
{
|
|
||||||
_devModeEnabled = spawnRoot(rootHelperPath(), @[@"check-dev-mode"], nil, nil) == 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_devModeEnabled = YES;
|
|
||||||
}
|
|
||||||
[self reloadSpecifiers];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableArray*)specifiers
|
- (NSMutableArray*)specifiers
|
||||||
@ -92,26 +82,6 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
|||||||
[_specifiers addObject:updateTrollStoreSpecifier];
|
[_specifiers addObject:updateTrollStoreSpecifier];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_devModeEnabled)
|
|
||||||
{
|
|
||||||
PSSpecifier* enableDevModeGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
|
||||||
enableDevModeGroupSpecifier.name = @"Developer Mode";
|
|
||||||
[enableDevModeGroupSpecifier setProperty:@"Some apps require developer mode enabled to launch. This requires a reboot to take effect." forKey:@"footerText"];
|
|
||||||
[_specifiers addObject:enableDevModeGroupSpecifier];
|
|
||||||
|
|
||||||
PSSpecifier* enableDevModeSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Enable Developer Mode"
|
|
||||||
target:self
|
|
||||||
set:nil
|
|
||||||
get:nil
|
|
||||||
detail:nil
|
|
||||||
cell:PSButtonCell
|
|
||||||
edit:nil];
|
|
||||||
enableDevModeSpecifier.identifier = @"enableDevMode";
|
|
||||||
[enableDevModeSpecifier setProperty:@YES forKey:@"enabled"];
|
|
||||||
enableDevModeSpecifier.buttonAction = @selector(enableDevModePressed);
|
|
||||||
[_specifiers addObject:enableDevModeSpecifier];
|
|
||||||
}
|
|
||||||
|
|
||||||
PSSpecifier* utilitiesGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
PSSpecifier* utilitiesGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||||
utilitiesGroupSpecifier.name = @"Utilities";
|
utilitiesGroupSpecifier.name = @"Utilities";
|
||||||
[utilitiesGroupSpecifier setProperty:@"If an app does not immediately appear after installation, respring here and it should appear afterwards." forKey:@"footerText"];
|
[utilitiesGroupSpecifier setProperty:@"If an app does not immediately appear after installation, respring here and it should appear afterwards." forKey:@"footerText"];
|
||||||
@ -399,37 +369,6 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
|||||||
[TSInstallationController installLdid];
|
[TSInstallationController installLdid];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)enableDevModePressed
|
|
||||||
{
|
|
||||||
int ret = spawnRoot(rootHelperPath(), @[@"arm-dev-mode"], nil, nil);
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
UIAlertController* rebootNotification = [UIAlertController alertControllerWithTitle:@"Reboot Required"
|
|
||||||
message:@"After rebooting, select \"Turn On\" to enable developer mode."
|
|
||||||
preferredStyle:UIAlertControllerStyleAlert
|
|
||||||
];
|
|
||||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action)
|
|
||||||
{
|
|
||||||
[self reloadSpecifiers];
|
|
||||||
}];
|
|
||||||
[rebootNotification addAction:closeAction];
|
|
||||||
|
|
||||||
UIAlertAction* rebootAction = [UIAlertAction actionWithTitle:@"Reboot Now" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
|
|
||||||
{
|
|
||||||
spawnRoot(rootHelperPath(), @[@"reboot"], nil, nil);
|
|
||||||
}];
|
|
||||||
[rebootNotification addAction:rebootAction];
|
|
||||||
|
|
||||||
[TSPresentationDelegate presentViewController:rebootNotification animated:YES completion:nil];
|
|
||||||
} else {
|
|
||||||
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Error %d", ret] message:@"Failed to enable developer mode." preferredStyle:UIAlertControllerStyleAlert];
|
|
||||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
|
|
||||||
[errorAlert addAction:closeAction];
|
|
||||||
|
|
||||||
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)installPersistenceHelperPressed
|
- (void)installPersistenceHelperPressed
|
||||||
{
|
{
|
||||||
NSMutableArray* appCandidates = [NSMutableArray new];
|
NSMutableArray* appCandidates = [NSMutableArray new];
|
||||||
|
Loading…
Reference in New Issue
Block a user