mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-16 12:30:29 +00:00
301 lines
11 KiB
Objective-C
301 lines
11 KiB
Objective-C
//
|
|
// IDeviceJSBridgeInstallationProxy.m
|
|
// StikJIT
|
|
//
|
|
// Created by s s on 2025/4/25.
|
|
//
|
|
@import Foundation;
|
|
@import JavaScriptCore;
|
|
#import "JSSupport.h"
|
|
|
|
struct InstallationProxyCallbackContext {
|
|
int callbackId;
|
|
JSContext* context;
|
|
};
|
|
|
|
void installationProxyCallback(uint64_t progress, struct InstallationProxyCallbackContext* context) {
|
|
[context->context evaluateScript:[NSString stringWithFormat:@"handle_installation_proxy_js_callback(%d, %llu)", context->callbackId, progress]];
|
|
}
|
|
|
|
@implementation IDeviceJSBridge (InstallationProxy)
|
|
|
|
- (void)installation_proxy_connectWithBody:(NSDictionary *)body replyHandler:(nonnull void (^)(id _Nullable, NSString * _Nullable))replyHandler {
|
|
NSError* heartbeatErr = nil;
|
|
[JITEnableContext.shared ensureHeartbeatWithError:&heartbeatErr];
|
|
if(heartbeatErr) {
|
|
replyHandler(nil, heartbeatErr.localizedDescription);
|
|
return;
|
|
}
|
|
|
|
IdeviceProviderHandle* provider = [JITEnableContext.shared getTcpProviderHandle];
|
|
|
|
InstallationProxyClientHandle *client = NULL;
|
|
IdeviceFfiError* err = installation_proxy_connect(provider, &client);
|
|
if (err) {
|
|
replyHandler(nil, [self errFreeFromIdeviceFfiError:err]);
|
|
return;
|
|
}
|
|
int handleId = [self registerIdeviceHandle:client freeFunc:(void*)installation_proxy_client_free];
|
|
replyHandler(@(handleId), nil);
|
|
}
|
|
|
|
- (void)installation_proxy_get_appsWithBody:(NSDictionary *)body replyHandler:(nonnull void (^)(id _Nullable, NSString * _Nullable))replyHandler {
|
|
|
|
int clientId = [body[@"client"] intValue];
|
|
if(!handles[@(clientId)] || handles[@(clientId)].freeFunc != installation_proxy_client_free) {
|
|
replyHandler(nil, @"Invalid client handle");
|
|
return;
|
|
}
|
|
IDeviceHandle* clientHandleObj = handles[@(clientId)];
|
|
InstallationProxyClientHandle* client = clientHandleObj.handle;
|
|
NSString* applicationType = body[@"application_type"];
|
|
if(![applicationType isKindOfClass:NSString.class]) {
|
|
applicationType = nil;
|
|
}
|
|
|
|
NSArray* bundleIdentifiers = body[@"bundle_identifiers"];
|
|
|
|
int bundleIdentifiersCount;
|
|
const char** bundleIdentifiersCharArr = cstrArrFromNSArray(bundleIdentifiers, &bundleIdentifiersCount);
|
|
void *apps = NULL;
|
|
size_t apps_len = 0;
|
|
IdeviceFfiError* err = installation_proxy_get_apps(client, [applicationType UTF8String], bundleIdentifiersCharArr, bundleIdentifiersCount, &apps, &apps_len);
|
|
if(bundleIdentifiersCharArr){
|
|
free(bundleIdentifiersCharArr);
|
|
}
|
|
if (err) {
|
|
replyHandler(nil, [self errFreeFromIdeviceFfiError:err]);
|
|
return;
|
|
}
|
|
|
|
plist_t *app_list = (plist_t *)apps;
|
|
do {
|
|
NSMutableArray* ans = [[NSMutableArray alloc] init];
|
|
for(int i = 0; i < apps_len; ++i) {
|
|
NSError* err2 = 0;
|
|
NSDictionary* appDict = dictionaryFromPlist(app_list[i], &err2);
|
|
|
|
if(err2) {
|
|
replyHandler(nil, @"failed to parse plist data");
|
|
break;
|
|
}
|
|
[ans addObject:appDict];
|
|
}
|
|
replyHandler(ans, nil);
|
|
} while(0);
|
|
|
|
for(int i = 0; i < apps_len; ++i) {
|
|
plist_free(app_list[i]);
|
|
}
|
|
}
|
|
|
|
- (void)installation_proxy_installWithBody:(NSDictionary *)body replyHandler:(nonnull void (^)(id _Nullable, NSString * _Nullable))replyHandler {
|
|
|
|
|
|
int clientId = [body[@"client"] intValue];
|
|
if(!handles[@(clientId)] || handles[@(clientId)].freeFunc != installation_proxy_client_free) {
|
|
replyHandler(nil, @"Invalid client handle");
|
|
return;
|
|
}
|
|
IDeviceHandle* clientHandleObj = handles[@(clientId)];
|
|
InstallationProxyClientHandle* client = clientHandleObj.handle;
|
|
|
|
NSString* packagePath = body[@"package_path"];
|
|
if(![packagePath isKindOfClass:NSString.class]) {
|
|
replyHandler(nil, @"Invalid package path");
|
|
return;
|
|
}
|
|
|
|
NSDictionary* optionsDict = body[@"options"];
|
|
plist_t optionsPlist = 0;
|
|
if([optionsDict isKindOfClass:NSDictionary.class]) {
|
|
NSError* error = 0;
|
|
NSData* optionsNSData = plistDataFromDictionary(optionsDict, &error);
|
|
if(error) {
|
|
replyHandler(nil, [NSString stringWithFormat:@"failed to parse options %@", error.localizedDescription]);
|
|
return;
|
|
}
|
|
plist_from_memory((void*)[optionsNSData bytes], (uint32_t)[optionsNSData length], &optionsPlist, 0);
|
|
}
|
|
|
|
int callbackId = [body[@"callback_id"] intValue];
|
|
IdeviceFfiError* err = 0;
|
|
if(callbackId == -1) {
|
|
err = installation_proxy_install(client, [packagePath UTF8String], optionsPlist);
|
|
} else {
|
|
struct InstallationProxyCallbackContext context;
|
|
context.callbackId = callbackId;
|
|
context.context = self->context;
|
|
err = installation_proxy_install_with_callback(client, [packagePath UTF8String], optionsPlist, (void (*)(uint64_t, void *))installationProxyCallback, &context);
|
|
|
|
}
|
|
|
|
if(optionsPlist) {
|
|
plist_free(optionsPlist);
|
|
}
|
|
|
|
if(err) {
|
|
replyHandler(nil, [self errFreeFromIdeviceFfiError:err]);
|
|
return;
|
|
}
|
|
replyHandler(@YES, nil);
|
|
}
|
|
|
|
- (void)installation_proxy_upgradeWithBody:(NSDictionary *)body replyHandler:(nonnull void (^)(id _Nullable, NSString * _Nullable))replyHandler {
|
|
|
|
|
|
int clientId = [body[@"client"] intValue];
|
|
if(!handles[@(clientId)] || handles[@(clientId)].freeFunc != installation_proxy_client_free) {
|
|
replyHandler(nil, @"Invalid client handle");
|
|
return;
|
|
}
|
|
IDeviceHandle* clientHandleObj = handles[@(clientId)];
|
|
InstallationProxyClientHandle* client = clientHandleObj.handle;
|
|
|
|
NSString* packagePath = body[@"package_path"];
|
|
if(![packagePath isKindOfClass:NSString.class]) {
|
|
replyHandler(nil, @"Invalid package path");
|
|
return;
|
|
}
|
|
|
|
NSDictionary* optionsDict = body[@"options"];
|
|
plist_t optionsPlist = 0;
|
|
if([optionsDict isKindOfClass:NSDictionary.class]) {
|
|
NSError* error = 0;
|
|
NSData* optionsNSData = plistDataFromDictionary(optionsDict, &error);
|
|
if(error) {
|
|
replyHandler(nil, [NSString stringWithFormat:@"failed to parse options %@", error.localizedDescription]);
|
|
return;
|
|
}
|
|
plist_from_memory((void*)[optionsNSData bytes], (uint32_t)[optionsNSData length], &optionsPlist, 0);
|
|
}
|
|
|
|
int callbackId = [body[@"callback_id"] intValue];
|
|
IdeviceFfiError* err = 0;
|
|
if(callbackId == -1) {
|
|
err = installation_proxy_upgrade(client, [packagePath UTF8String], optionsPlist);
|
|
} else {
|
|
struct InstallationProxyCallbackContext context;
|
|
context.callbackId = callbackId;
|
|
context.context = self->context;
|
|
err = installation_proxy_upgrade_with_callback(client, [packagePath UTF8String], optionsPlist, (void (*)(uint64_t, void *))installationProxyCallback, &context);
|
|
|
|
}
|
|
|
|
if(optionsPlist) {
|
|
plist_free(optionsPlist);
|
|
}
|
|
|
|
if(err) {
|
|
replyHandler(nil, [self errFreeFromIdeviceFfiError:err]);
|
|
return;
|
|
}
|
|
replyHandler(@YES, nil);
|
|
}
|
|
|
|
- (void)installation_proxy_uninstallWithBody:(NSDictionary *)body replyHandler:(nonnull void (^)(id _Nullable, NSString * _Nullable))replyHandler {
|
|
|
|
|
|
int clientId = [body[@"client"] intValue];
|
|
if(!handles[@(clientId)] || handles[@(clientId)].freeFunc != installation_proxy_client_free) {
|
|
replyHandler(nil, @"Invalid client handle");
|
|
return;
|
|
}
|
|
IDeviceHandle* clientHandleObj = handles[@(clientId)];
|
|
InstallationProxyClientHandle* client = clientHandleObj.handle;
|
|
|
|
NSString* bundleId = body[@"bundle_id"];
|
|
if(![bundleId isKindOfClass:NSString.class]) {
|
|
replyHandler(nil, @"Invalid bundle id");
|
|
return;
|
|
}
|
|
|
|
NSDictionary* optionsDict = body[@"options"];
|
|
plist_t optionsPlist = 0;
|
|
if([optionsDict isKindOfClass:NSDictionary.class]) {
|
|
NSError* error = 0;
|
|
NSData* optionsNSData = plistDataFromDictionary(optionsDict, &error);
|
|
if(error) {
|
|
replyHandler(nil, [NSString stringWithFormat:@"failed to parse options %@", error.localizedDescription]);
|
|
return;
|
|
}
|
|
plist_from_memory((void*)[optionsNSData bytes], (uint32_t)[optionsNSData length], &optionsPlist, 0);
|
|
}
|
|
|
|
int callbackId = [body[@"callback_id"] intValue];
|
|
IdeviceFfiError* err = 0;
|
|
if(callbackId == -1) {
|
|
err = installation_proxy_uninstall(client, [bundleId UTF8String], optionsPlist);
|
|
} else {
|
|
struct InstallationProxyCallbackContext context;
|
|
context.callbackId = callbackId;
|
|
context.context = self->context;
|
|
err = installation_proxy_uninstall_with_callback(client, [bundleId UTF8String], optionsPlist, (void (*)(uint64_t, void *))installationProxyCallback, &context);
|
|
|
|
}
|
|
|
|
if(optionsPlist) {
|
|
plist_free(optionsPlist);
|
|
}
|
|
|
|
if(err) {
|
|
replyHandler(nil, [self errFreeFromIdeviceFfiError:err]);
|
|
return;
|
|
}
|
|
replyHandler(@YES, nil);
|
|
}
|
|
|
|
- (void)installation_proxy_browseWithBody:(NSDictionary *)body replyHandler:(nonnull void (^)(id _Nullable, NSString * _Nullable))replyHandler {
|
|
|
|
int clientId = [body[@"client"] intValue];
|
|
if(!handles[@(clientId)] || handles[@(clientId)].freeFunc != installation_proxy_client_free) {
|
|
replyHandler(nil, @"Invalid client handle");
|
|
return;
|
|
}
|
|
IDeviceHandle* clientHandleObj = handles[@(clientId)];
|
|
InstallationProxyClientHandle* client = clientHandleObj.handle;
|
|
|
|
NSDictionary* optionsDict = body[@"options"];
|
|
plist_t optionsPlist = 0;
|
|
if([optionsDict isKindOfClass:NSDictionary.class]) {
|
|
NSError* error = 0;
|
|
NSData* optionsNSData = plistDataFromDictionary(optionsDict, &error);
|
|
if(error) {
|
|
replyHandler(nil, [NSString stringWithFormat:@"failed to parse options %@", error.localizedDescription]);
|
|
return;
|
|
}
|
|
plist_from_memory((void*)[optionsNSData bytes], (uint32_t)[optionsNSData length], &optionsPlist, 0);
|
|
}
|
|
|
|
plist_t *app_list = NULL;
|
|
size_t apps_len = 0;
|
|
IdeviceFfiError* err = installation_proxy_browse(client, optionsPlist, &app_list, &apps_len);
|
|
|
|
if (err) {
|
|
replyHandler(nil, [self errFreeFromIdeviceFfiError:err]);
|
|
return;
|
|
}
|
|
|
|
do {
|
|
NSMutableArray* ans = [[NSMutableArray alloc] init];
|
|
for(int i = 0; i < apps_len; ++i) {
|
|
NSError* err2 = 0;
|
|
NSDictionary* appDict = dictionaryFromPlist(app_list[i], &err2);
|
|
|
|
if(err2) {
|
|
replyHandler(nil, @"failed to parse plist data");
|
|
break;
|
|
}
|
|
[ans addObject:appDict];
|
|
}
|
|
replyHandler(ans, nil);
|
|
} while(0);
|
|
|
|
for(int i = 0; i < apps_len; ++i) {
|
|
plist_free(app_list[i]);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
@end
|