Skip to content

Commit

Permalink
Merge pull request #11942 from jeeeyul/master
Browse files Browse the repository at this point in the history
Fixes iOS exit freezing, Selective PTRACE syscall
  • Loading branch information
unknownbrackets committed Mar 28, 2019
2 parents ed1aa74 + 53e254d commit 62928e1
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 97 deletions.
6 changes: 6 additions & 0 deletions ios/ViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,12 @@ - (void)controllerButtonPressed:(BOOL)pressed keyCode:(keycode_t)keyCode
NativeKey(key);
}

// Enables tapping for edge area.
-(UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
return UIRectEdgeAll;
}

- (void)setupController:(GCController *)controller
{
self.gameController = controller;
Expand Down
65 changes: 65 additions & 0 deletions ios/codesign.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/

#ifndef _SYS_CODESIGN_H_
#define _SYS_CODESIGN_H_

#include <sys/types.h>

/* code signing attributes of a process */
#define CS_VALID 0x0001 /* dynamically valid */
#define CS_HARD 0x0100 /* don't load invalid pages */
#define CS_KILL 0x0200 /* kill process if it becomes invalid */
#define CS_EXEC_SET_HARD 0x1000 /* set CS_HARD on any exec'ed process */
#define CS_EXEC_SET_KILL 0x2000 /* set CS_KILL on any exec'ed process */
#define CS_KILLED 0x10000 /* was killed by kernel for invalidity */
#define CS_RESTRICT 0x20000 /* tell dyld to treat restricted */

/* csops operations */
#define CS_OPS_STATUS 0 /* return status */
#define CS_OPS_MARKINVALID 1 /* invalidate process */
#define CS_OPS_MARKHARD 2 /* set HARD flag */
#define CS_OPS_MARKKILL 3 /* set KILL flag (sticky) */
#define CS_OPS_PIDPATH 4 /* get executable's pathname */
#define CS_OPS_CDHASH 5 /* get code directory hash */
#define CS_OPS_PIDOFFSET 6 /* get offset of active Mach-o slice */
#define CS_OPS_ENTITLEMENTS_BLOB 7 /* get entitlements blob */
#define CS_OPS_MARKRESTRICT 8 /* set RESTRICT flag (sticky) */

#ifndef KERNEL

__BEGIN_DECLS

/* code sign operations */
int csops(pid_t pid, unsigned int ops, void * useraddr, size_t usersize);

__END_DECLS

#endif /* ! KERNEL */

#endif /* _SYS_CODESIGN_H_ */
167 changes: 70 additions & 97 deletions ios/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#import <stdlib.h>
#import <sys/syscall.h>
#import <AudioToolbox/AudioToolbox.h>
#import "codesign.h"

#import "AppDelegate.h"
#import "PPSSPPUIApplication.h"
Expand All @@ -14,89 +15,53 @@
#include "base/NativeApp.h"
#include "profiler/profiler.h"

@interface UIApplication (Private)
-(void) suspend;
-(void) terminateWithSuccess;
@end
#define CS_OPS_STATUS 0 /* return status */
#define CS_DEBUGGED 0x10000000 /* process is currently or has previously been debugged and allowed to run with invalid pages */
int csops(pid_t pid, unsigned int ops, void * useraddr, size_t usersize);

@interface UIApplication (SpringBoardAnimatedExit)
-(void) animatedExit;
@end

@implementation UIApplication (SpringBoardAnimatedExit)
-(void) animatedExit {
[sharedViewController shutdown];

BOOL multitaskingSupported = NO;
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) {
multitaskingSupported = [UIDevice currentDevice].multitaskingSupported;
}
if ([self respondsToSelector:@selector(suspend)]) {
if (multitaskingSupported) {
[self beginBackgroundTaskWithExpirationHandler:^{}];
[self performSelector:@selector(exit) withObject:nil afterDelay:0.4];
}
[self suspend];
} else {
[self exit];
}
}

-(void) exit {
[sharedViewController shutdown];

if ([self respondsToSelector:@selector(terminateWithSuccess)]) {
[self terminateWithSuccess];
} else {
exit(0);
}
}
@end

std::string System_GetProperty(SystemProperty prop) {
switch (prop) {
case SYSPROP_NAME:
return "iOS:";
case SYSPROP_LANGREGION:
return "en_US";
default:
return "";
case SYSPROP_NAME:
return "iOS:";
case SYSPROP_LANGREGION:
return "en_US";
default:
return "";
}
}

int System_GetPropertyInt(SystemProperty prop) {
switch (prop) {
case SYSPROP_AUDIO_SAMPLE_RATE:
return 44100;
case SYSPROP_DISPLAY_REFRESH_RATE:
return 60000;
case SYSPROP_DEVICE_TYPE:
return DEVICE_TYPE_MOBILE;
default:
return -1;
case SYSPROP_AUDIO_SAMPLE_RATE:
return 44100;
case SYSPROP_DISPLAY_REFRESH_RATE:
return 60000;
case SYSPROP_DEVICE_TYPE:
return DEVICE_TYPE_MOBILE;
default:
return -1;
}
}

bool System_GetPropertyBool(SystemProperty prop) {
switch (prop) {
case SYSPROP_HAS_BACK_BUTTON:
return false;
case SYSPROP_APP_GOLD:
case SYSPROP_HAS_BACK_BUTTON:
return false;
case SYSPROP_APP_GOLD:
#ifdef GOLD
return true;
return true;
#else
return false;
return false;
#endif
default:
return false;
default:
return false;
}
}

void System_SendMessage(const char *command, const char *parameter) {
if (!strcmp(command, "finish")) {
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] animatedExit];
});
exit(0);
}
}

Expand All @@ -107,49 +72,57 @@ void System_AskForPermission(SystemPermission permission) {}

BOOL SupportsTaptic()
{
// we're on an iOS version that cannot instantiate UISelectionFeedbackGenerator, so no.
if(!NSClassFromString(@"UISelectionFeedbackGenerator"))
{
return NO;
}
// http://www.mikitamanko.com/blog/2017/01/29/haptic-feedback-with-uifeedbackgenerator/
// use private API against UIDevice to determine the haptic stepping
// 2 - iPhone 7 or above, full taptic feedback
// 1 - iPhone 6S, limited taptic feedback
// 0 - iPhone 6 or below, no taptic feedback
NSNumber* val = (NSNumber*)[[UIDevice currentDevice] valueForKey:@"feedbackSupportLevel"];
return [val intValue] >= 2;
// we're on an iOS version that cannot instantiate UISelectionFeedbackGenerator, so no.
if(!NSClassFromString(@"UISelectionFeedbackGenerator"))
{
return NO;
}
// http://www.mikitamanko.com/blog/2017/01/29/haptic-feedback-with-uifeedbackgenerator/
// use private API against UIDevice to determine the haptic stepping
// 2 - iPhone 7 or above, full taptic feedback
// 1 - iPhone 6S, limited taptic feedback
// 0 - iPhone 6 or below, no taptic feedback
NSNumber* val = (NSNumber*)[[UIDevice currentDevice] valueForKey:@"feedbackSupportLevel"];
return [val intValue] >= 2;
}

void Vibrate(int mode) {
if(SupportsTaptic())
{
PPSSPPUIApplication* app = (PPSSPPUIApplication*)[UIApplication sharedApplication];
if(app.feedbackGenerator == nil)
{
app.feedbackGenerator = [[UISelectionFeedbackGenerator alloc] init];
[app.feedbackGenerator prepare];
}
[app.feedbackGenerator selectionChanged];
}
else
{
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
NSArray *pattern = @[@YES, @30, @NO, @2];
dictionary[@"VibePattern"] = pattern;
dictionary[@"Intensity"] = @2;
AudioServicesPlaySystemSoundWithVibration(kSystemSoundID_Vibrate, nil, dictionary);
}
if(SupportsTaptic())
{
PPSSPPUIApplication* app = (PPSSPPUIApplication*)[UIApplication sharedApplication];
if(app.feedbackGenerator == nil)
{
app.feedbackGenerator = [[UISelectionFeedbackGenerator alloc] init];
[app.feedbackGenerator prepare];
}
[app.feedbackGenerator selectionChanged];
}
else
{
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
NSArray *pattern = @[@YES, @30, @NO, @2];
dictionary[@"VibePattern"] = pattern;
dictionary[@"Intensity"] = @2;
AudioServicesPlaySystemSoundWithVibration(kSystemSoundID_Vibrate, nil, dictionary);
}
}

int main(int argc, char *argv[])
{
// Simulates a debugger. Makes it possible to use JIT (though only W^X)
syscall(SYS_ptrace, 0 /*PTRACE_TRACEME*/, 0, 0, 0);
// see https://github.com/hrydgard/ppsspp/issues/11905#issuecomment-476871010
uint32_t flags;
csops(getpid(), CS_OPS_STATUS, &flags, 0);
if (flags & CS_DEBUGGED){
//being run either under a debugger or under Electra already
}
else{
// Simulates a debugger. Makes it possible to use JIT (though only W^X)
syscall(SYS_ptrace, 0 /*PTRACE_TRACEME*/, 0, 0, 0);
}

PROFILE_INIT();

Expand Down

0 comments on commit 62928e1

Please sign in to comment.