iOS: Remove availability checks for versions below the 15.0 minimum

Also drops what they guarded: the pre-14 UIImagePickerController and
document picker fallbacks, the psychic paper entitlement workaround
(fixed in 13.5), and the CS_EXECSEG_ALLOW_UNSIGNED JIT probe, which
returned false on everything from 14.4 on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-11 16:13:29 +02:00
1 parent 2a1269f572
commit ebab68ac0a
5 files changed
+37 -138

No files matched your search

+6 -16
View File
@@ -286,22 +286,12 @@ void DarwinFileSystemServices::presentDirectoryPanel(
return;
// Open, not import - we don't want the files copied, we handle that ourselves if needed.
UIDocumentPickerViewController *pickerVC;
if (@available(iOS 14.0, *)) {
NSMutableArray<UTType *> *types = [NSMutableArray array];
if (allowDirectories)
[types addObject:UTTypeFolder];
if (allowFiles)
[types addObject:UTTypeItem];
pickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:types];
} else {
NSMutableArray<NSString *> *types = [NSMutableArray array];
if (allowDirectories)
[types addObject:(__bridge NSString *)kUTTypeFolder];
if (allowFiles)
[types addObject:(__bridge NSString *)kUTTypeItem];
pickerVC = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:types inMode:UIDocumentPickerModeOpen];
}
NSMutableArray<UTType *> *types = [NSMutableArray array];
if (allowDirectories)
[types addObject:UTTypeFolder];
if (allowFiles)
[types addObject:UTTypeItem];
UIDocumentPickerViewController *pickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:types];
// What if you wanted to go to heaven, but then God showed you the next few lines?
// serious note: have to do this, because __pickerDelegate has to stay retained as a class property
__pickerDelegate = (void *)CFBridgingRetain([[DocumentPickerDelegate alloc] initWithCallback:panelCallback]);
+24 -33
View File
@@ -30,10 +30,8 @@ bool InitController(GCController *controller) {
return false;
}
if (@available(iOS 14.0, tvOS 14.0, *)) {
for (GCControllerElement* element in controller.physicalInputProfile.allElements) {
element.preferredSystemGestureState = GCSystemGestureStateDisabled;
}
for (GCControllerElement* element in controller.physicalInputProfile.allElements) {
element.preferredSystemGestureState = GCSystemGestureStateDisabled;
}
const std::string controllerName = [controller.vendorName ?: @"Gamepad" UTF8String];
@@ -112,12 +110,10 @@ bool InitController(GCController *controller) {
};
}
if (@available(iOS 14.0, *)) {
if (extendedProfile.buttonHome != nil) {
extendedProfile.buttonHome.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
controllerButtonPressed(pressed, NKCODE_HOME);
};
}
if (extendedProfile.buttonHome != nil) {
extendedProfile.buttonHome.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
controllerButtonPressed(pressed, NKCODE_HOME);
};
}
extendedProfile.leftThumbstick.xAxis.valueChangedHandler = ^(GCControllerAxisInput *axis, float value) {
@@ -158,10 +154,8 @@ bool InitController(GCController *controller) {
}
void ShutdownController(GCController *controller) {
if (@available(iOS 14.0, tvOS 14.0, *)) {
for (GCControllerElement* element in controller.physicalInputProfile.allElements) {
element.preferredSystemGestureState = GCSystemGestureStateEnabled;
}
for (GCControllerElement* element in controller.physicalInputProfile.allElements) {
element.preferredSystemGestureState = GCSystemGestureStateEnabled;
}
static const InputKeyCode keycodes[] = {
NKCODE_BUTTON_1,
@@ -308,25 +302,22 @@ void SendKeyboardChars(std::string_view str) {
}
static void SendPresses(NSSet<UIPress *> *presses, KeyInputFlags flags) {
// UIPress.key, and with it hardware keyboard support, needs 13.4.
if (@available(iOS 13.4, *)) {
for (UIPress *press in presses) {
if (!press.key) {
// I guess we could support remotes and stuff.
continue;
}
InputKeyCode code = HIDUsageToInputKeyCode(press.key.keyCode);
if (code != NKCODE_UNKNOWN) {
KeyInput input{};
input.deviceId = DEVICE_ID_KEYBOARD;
input.keyCode = code;
input.flags = flags;
NativeKey(input);
}
if ((flags & KeyInputFlags::DOWN) && press.key.characters) {
std::string chars([press.key.characters UTF8String]);
SendKeyboardChars(chars);
}
for (UIPress *press in presses) {
if (!press.key) {
// I guess we could support remotes and stuff.
continue;
}
InputKeyCode code = HIDUsageToInputKeyCode(press.key.keyCode);
if (code != NKCODE_UNKNOWN) {
KeyInput input{};
input.deviceId = DEVICE_ID_KEYBOARD;
input.keyCode = code;
input.flags = flags;
NativeKey(input);
}
if ((flags & KeyInputFlags::DOWN) && press.key.characters) {
std::string chars([press.key.characters UTF8String]);
SendKeyboardChars(chars);
}
}
}
-1
View File
@@ -9,7 +9,6 @@
#import "LocationHelper.h"
@interface PPSSPPBaseViewController : UIViewController<
UIImagePickerControllerDelegate, UINavigationControllerDelegate,
PHPickerViewControllerDelegate,
CameraFrameDelegate, LocationHandlerDelegate,
UIGestureRecognizerDelegate>
+5 -36
View File
@@ -246,28 +246,17 @@ static int GetPickerRequestId(id picker) {
NSLog(@"Picking photo to save to %@ (id: %d)", saveFilename, requestId);
NSString *targetFilename = [saveFilename copy];
if (@available(iOS 14.0, *)) {
PHPickerConfiguration *config = [[PHPickerConfiguration alloc] initWithPhotoLibrary:PHPhotoLibrary.sharedPhotoLibrary];
config.selectionLimit = 1;
config.filter = [PHPickerFilter imagesFilter];
PHPickerConfiguration *config = [[PHPickerConfiguration alloc] initWithPhotoLibrary:PHPhotoLibrary.sharedPhotoLibrary];
config.selectionLimit = 1;
config.filter = [PHPickerFilter imagesFilter];
PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:config];
picker.delegate = self;
SetPickerContext(picker, targetFilename, requestId);
[self presentViewController:picker animated:YES completion:nil];
return;
}
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
// Images only keeps the picker from doing extra video-related setup.
picker.mediaTypes = @[@"public.image"];
PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:config];
picker.delegate = self;
SetPickerContext(picker, targetFilename, requestId);
[self presentViewController:picker animated:YES completion:nil];
}
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14.0)) {
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results {
NSString *targetFilename = GetPickerFilename(picker);
int requestId = GetPickerRequestId(picker);
@@ -298,26 +287,6 @@ static int GetPickerRequestId(id picker) {
}];
}
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
NSString *targetFilename = GetPickerFilename(picker);
int requestId = GetPickerRequestId(picker);
UIImage *image = info[UIImagePickerControllerOriginalImage];
[self savePickedImage:image toFilename:targetFilename requestId:requestId];
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
NSLog(@"User cancelled image picker");
int requestId = GetPickerRequestId(picker);
[picker dismissViewControllerAnimated:YES completion:nil];
g_requestManager.PostSystemFailure(requestId);
}
- (void)handleSwipeFrom:(UIScreenEdgePanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateEnded) {
KeyInput key;
+2 -52
View File
@@ -20,7 +20,6 @@
#import <stdio.h>
#import <stdlib.h>
#import <sys/syscall.h>
#import <sys/utsname.h>
#import "AppDelegate.h"
#import "ViewControllerCommon.h"
@@ -83,16 +82,6 @@ static void *exception_handler(void *argument) {
static NSDictionary *parse_entitlements(const void *entitlements, size_t length) {
char *copy = (char *)malloc(length);
memcpy(copy, entitlements, length);
// strip out psychic paper entitlement hiding
if (@available(iOS 13.5, *)) {
} else {
static const char *needle = "<!---><!-->";
char *found = strnstr(copy, needle, length);
if (found) {
memset(found, ' ', strlen(needle));
}
}
NSData *data = [NSData dataWithBytes:copy length:length];
free(copy);
@@ -206,43 +195,6 @@ bool jb_has_cs_disabled(void) {
return !csops(getpid(), CS_OPS_STATUS, &flags, sizeof(flags)) && (flags & ~CS_KILL) == flags;
}
#define _COMM_PAGE_START_ADDRESS (0x0000000FFFFFC000ULL) /* In TTBR0 */
#define _COMM_PAGE_APRR_SUPPORT (_COMM_PAGE_START_ADDRESS+0x10C)
static bool is_device_A12_or_newer(void) {
// devices without APRR are definitely < A12
char aprr_support = *(volatile char *)_COMM_PAGE_APRR_SUPPORT;
if (aprr_support == 0) {
return false;
}
// we still have A11 devices that support APRR
struct utsname systemInfo;
if (uname(&systemInfo) != 0) {
return false;
}
// iPhone 8, 8 Plus, and iPhone X
if (strncmp("iPhone10,", systemInfo.machine, 9) == 0) {
return false;
} else {
return true;
}
}
bool jb_has_cs_execseg_allow_unsigned(void) {
NSDictionary *entitlements = cached_app_entitlements();
if (@available(iOS 14.2, *)) {
if (@available(iOS 14.4, *)) {
return false; // iOS 14.4 broke it again
}
// technically we need to check the Code Directory and make sure
// CS_EXECSEG_ALLOW_UNSIGNED is set but we assume that it is properly
// signed, which should reflect the get-task-allow entitlement
return is_device_A12_or_newer() && [entitlements[@"get-task-allow"] boolValue];
} else {
return false;
}
}
static bool jb_has_debugger_attached(void) {
int flags;
return !csops(getpid(), CS_OPS_STATUS, &flags, sizeof(flags)) && flags & CS_DEBUGGED;
@@ -697,8 +649,8 @@ AudioBackend *System_CreateAudioBackend() {
int main(int argc, char *argv[]) {
version = [[[UIDevice currentDevice] systemVersion] UTF8String];
if (1 != sscanf(version.c_str(), "%d", &g_iosVersionMajor)) {
// Just set it to 14.0 if the parsing fails for whatever reason.
g_iosVersionMajor = 14;
// Just set it to 15 (the minimum) if the parsing fails for whatever reason.
g_iosVersionMajor = 15;
}
g_logManager.EnableOutput(LogOutput::Stdio);
@@ -718,8 +670,6 @@ int main(int argc, char *argv[]) {
INFO_LOG(Log::System, "JIT: found entitlement\n");
} else if (jb_has_cs_disabled()) {
INFO_LOG(Log::System, "JIT: CS_KILL disabled\n");
} else if (jb_has_cs_execseg_allow_unsigned()) {
INFO_LOG(Log::System, "JIT: CS_EXECSEG_ALLOW_UNSIGNED set\n");
} else if (jb_enable_ptrace_hack()) {
INFO_LOG(Log::System, "JIT: ptrace() hack supported\n");
} else {