diff --git a/CyDelete.xm b/CyDelete.xm index 634245d..ead3208 100644 --- a/CyDelete.xm +++ b/CyDelete.xm @@ -1,14 +1,18 @@ // -// CyDelete8.xm -// CyDelete8 +// CyDelete.xm +// CyDelete // // Created by Ryan Burke on 02.01.2014. // Copyright (c) 2014 Ryan Burke. All rights reserved. // +// Modified by Pal Lockheart on 12.04.2016. +// Copyright (c) 2016 Pal Lockheart. All rights reserved. +// #import #import #include +#import #import #import #import @@ -165,6 +169,14 @@ static id ownerForSBApplication(SBApplication *application) { return package; } +static BOOL isOfficialUninstallable(SBApplication *application) { + return [application isSystemApplication] + || [application isInternalApplication] + || [application isWebApplication] + || [[application path] hasPrefix:@"/private/var/mobile/Containers/Bundle/Application"] //iOS 9.1.x- + || [[application path] hasPrefix:@"/private/var/containers/Bundle/Application"]; //iOS 9.2.x+ +} + @implementation CDUninstallOperation - (id)init { if((self = [super init]) != nil) { @@ -219,7 +231,7 @@ static id ownerForSBApplication(SBApplication *application) { - (void)displayError { NSString *body = [NSString stringWithFormat:CDLocalizedString(@"PACKAGE_UNINSTALL_ERROR_BODY"), _package]; UIAlertView *delView = [[UIAlertView alloc] initWithTitle:CDLocalizedString(@"PACKAGE_UNINSTALL_ERROR_TITLE") message:body delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil]; - [delView show]; + [delView show]; } -(void)displayRespring { @@ -283,10 +295,10 @@ static void removeBundleFromMIList(NSString *bundle) { //Show the user an error message warning them that we didn't remove the application. NSString *nonCydiaText = [NSString stringWithFormat:CDLocalizedString(@"PACKAGE_NOT_CYDIA_BODY"), package]; UIAlertView *nonCydiaAlert = [[UIAlertView alloc] initWithTitle:CDLocalizedString(@"PACKAGE_NOT_CYDIA_TITLE") - message:nonCydiaText - delegate:nil - cancelButtonTitle:@"Okay" - otherButtonTitles:nil]; + message:nonCydiaText + delegate:nil + cancelButtonTitle:@"Okay" + otherButtonTitles:nil]; [nonCydiaAlert show]; } else { @@ -298,10 +310,31 @@ static void removeBundleFromMIList(NSString *bundle) { } %end -@interface SBApplicationIcon (CyDelete) - -(BOOL)cydelete_allowsUninstall; - -(void)cydelete_uninstallClicked; -@end +static BOOL cydelete_IOSVersionAbove92() { + return kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_9_2; +} + +static BOOL cydelete_allowsUninstall(SBIcon *arg) { + //Get the bundle ID for this application. + NSString *bundle = nil; + if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) { + bundle = [[arg application] bundleIdentifier]; + } + else { + bundle = [[arg application] displayName]; + } + //If the application is an Apple application. + bool isApple = ([bundle hasPrefix:@"com.apple."] && ![bundle hasPrefix:@"com.apple.samplecode."]); + //If the application is Cydia and user has protected it. + bool isCydia = ([bundle isEqualToString:@"com.saurik.Cydia"] && getProtectCydia()); + //If the application is Cydia and user has protected it. + bool isPangu = ([bundle isEqualToString:@"io.pangu.nvwastone"] && getProtectPangu()); + //If any of these match then we don't want to allow uninstall. + if(isApple || isCydia || isPangu || !getEnabled() || getFreeMemory() < 20 ) { + return NO; + } + return YES; +} static void uninstallClickedForIcon(SBIcon *self) { //Get the application for this icon. @@ -325,59 +358,80 @@ static void uninstallClickedForIcon(SBIcon *self) { } } +static BOOL _forceCydia; +@interface SBApplicationIcon(CyDelete) +@property (nonatomic) BOOL forceCydia; +@end + + +@interface LSApplicationWorkspace : NSObject ++ (id) defaultWorkspace; +- (BOOL) unregisterApplication:(id)application; +- (BOOL) registerApplicationDictionary:(id)application; +@end + %hook SBIconController + - (_Bool)iconViewDisplaysCloseBox:(id)arg1{ + if([arg1 class] != %c(SBIconView) && [arg1 class] != %c(SBActivatorIcon)) { + return %orig(arg1); + } + SBIconView *iconView = arg1; + SBIcon *icon = [iconView icon]; + return cydelete_allowsUninstall(icon); + } - (void)iconCloseBoxTapped:(id)_i { %log; SBIconView *iconView = _i; SBIcon *icon = [iconView icon]; + SBApplicationIcon *appicon = (SBApplicationIcon *)icon; SBApplication *app = [icon application]; id pkgName = ownerForSBApplication(app); if(pkgName != [NSNull null]) { uninstallClickedForIcon(icon); } - %orig; + if(cydelete_IOSVersionAbove92() && [[iconPackagesDict allKeys] containsObject:[app bundleIdentifier]]) { + //new mechanism: iOS 9.2 above will not automatically trigger uninstall, we've to call it manually + appicon.forceCydia = YES; + UIAlertController* alert=[UIAlertController alertControllerWithTitle:[appicon uninstallAlertTitle] message:[appicon uninstallAlertBody] preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:[appicon uninstallAlertCancelTitle] style:UIAlertActionStyleDefault handler:nil]]; + [alert addAction:[UIAlertAction actionWithTitle:[appicon uninstallAlertConfirmTitle] style:UIAlertActionStyleCancel handler:^(UIAlertAction* _Nonnull action) + { + Class $LSApplicationWorkspace = objc_getClass("LSApplicationWorkspace"); + [[$LSApplicationWorkspace defaultWorkspace] unregisterApplication:[NSURL fileURLWithPath:[app path]]]; + Class $SBApplicationController = objc_getClass("SBApplicationController"); + [[$SBApplicationController sharedInstance] uninstallApplication:app]; + }]]; + appicon.forceCydia = NO; + [self presentViewController: alert animated:YES completion:nil]; + }else{ + %orig; + } } %end %hook SBApplicationIcon - - %new(c@:) - -(BOOL)cydelete_allowsUninstall { - //Get the bundle ID for this application. - NSString *bundle = nil; - if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) { - bundle = [[self application] bundleIdentifier]; - } - else { - bundle = [[self application] displayName]; - } - //If the application is an Apple application. - bool isApple = ([bundle hasPrefix:@"com.apple."] && ![bundle hasPrefix:@"com.apple.samplecode."]); - //If the application is Cydia and user has protected it. - bool isCydia = ([bundle isEqualToString:@"com.saurik.Cydia"] && getProtectCydia()); - //If the application is Cydia and user has protected it. - bool isPangu = ([bundle isEqualToString:@"io.pangu.loader"] && getProtectPangu()); - //If any of these match then we don't want to allow uninstall. - if(isApple || isCydia || isPangu || !getEnabled() || getFreeMemory() < 20 ) { - return NO; - } - return YES; + %new + - (BOOL)forceCydia{ + return _forceCydia; + } + %new + - (void)setForceCydia:(BOOL)force{ + _forceCydia = force; } + //iOS 7/8/9.0-9.1 compatible code -(BOOL)allowsCloseBox { if([self class] != %c(SBApplicationIcon) && [self class] != %c(SBActivatorIcon)) { return %orig; } - return [self cydelete_allowsUninstall]; + return cydelete_allowsUninstall(self); } - -(BOOL)allowsUninstall { if([self class] != %c(SBApplicationIcon) && [self class] != %c(SBActivatorIcon)) { return %orig; } - return [self cydelete_allowsUninstall]; + return cydelete_allowsUninstall(self); } - -(void)closeBoxClicked:(id)event { if([self class] != %c(SBApplicationIcon) && [self class] != %c(SBActivatorIcon)) { %orig; @@ -386,7 +440,6 @@ static void uninstallClickedForIcon(SBIcon *self) { uninstallClickedForIcon(self); %orig; } - -(void)uninstallClicked:(id)event { if([self class] != %c(SBApplicationIcon) && [self class] != %c(SBActivatorIcon)) { %orig; @@ -397,11 +450,16 @@ static void uninstallClickedForIcon(SBIcon *self) { } -(NSString *)uninstallAlertTitle { - return [NSString stringWithFormat:SBLocalizedString(@"UNINSTALL_ICON_TITLE"), + if(!_forceCydia && isOfficialUninstallable([self application])) + return %orig; + return [NSString stringWithFormat:cydelete_IOSVersionAbove92() ? SBLocalizedString(@"UNINSTALL_ICON_TITLE_DELETE_WITH_NAME") : SBLocalizedString(@"UNINSTALL_ICON_TITLE"), [[self application] displayName]]; } -(NSString *)uninstallAlertBody { + %log; + if(!_forceCydia && isOfficialUninstallable([self application])) + return %orig; NSString *bundle = nil; @@ -427,11 +485,15 @@ static void uninstallClickedForIcon(SBIcon *self) { } -(NSString *)uninstallAlertConfirmTitle { - return SBLocalizedString(@"UNINSTALL_ICON_CONFIRM"); + if(!_forceCydia && isOfficialUninstallable([self application])) + return %orig; + return cydelete_IOSVersionAbove92() ? SBLocalizedString(@"UNINSTALL_ICON_BUTTON_DELETE") : SBLocalizedString(@"UNINSTALL_ICON_CONFIRM"); } -(NSString *)uninstallAlertCancelTitle { - return SBLocalizedString(@"UNINSTALL_ICON_CANCEL"); + if(!_forceCydia && isOfficialUninstallable([self application])) + return %orig; + return cydelete_IOSVersionAbove92() ? SBLocalizedString(@"UNINSTALL_ICON_BUTTON_CANCEL") : SBLocalizedString(@"UNINSTALL_ICON_CANCEL"); } %end @@ -441,4 +503,4 @@ static void uninstallClickedForIcon(SBIcon *self) { iconPackagesDict = [[NSMutableDictionary alloc] init]; uninstallQueue = [[NSOperationQueue alloc] init]; [uninstallQueue setMaxConcurrentOperationCount:1]; -} +} \ No newline at end of file diff --git a/CyDelete/CyDeleteListController.mm b/CyDelete/CyDeleteListController.mm index 1f1d775..fd80a55 100644 --- a/CyDelete/CyDeleteListController.mm +++ b/CyDelete/CyDeleteListController.mm @@ -11,7 +11,7 @@ @interface CyDeleteListController : PSListController - (id)specifiers; -- (void)ryanDonate:(id)arg; +- (void)donate:(id)arg; - (void)viewSource:(id)arg; @end @@ -30,6 +30,10 @@ - (id)navigationTitle { return [[self bundle] localizedStringForKey:[super title] value:[super title] table:nil]; } +- (id)localized:(NSString *)key{ + return [[self bundle] localizedStringForKey:key value:key table:nil]; +} + - (id)localizedSpecifiersWithSpecifiers:(NSArray *)specifiers { NSLog(@"localizedSpecifiersWithSpecifiers"); @@ -54,8 +58,37 @@ - (id)localizedSpecifiersWithSpecifiers:(NSArray *)specifiers { return specifiers; } -- (void)ryanDonate:(id)arg { - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4VBFWEFBUF56N"]]; +- (void)donate:(id)arg { + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4VBFWEFBUF56N"]]; +} + +- (void)donate2:(id)arg { + UIAlertController* alert=[UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"%@ palxex",[self localized:@"DONATE"]] message:nil preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:[self localized:@"BITCOIN"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* _Nonnull action) + { + NSURL *targetURL = [NSURL URLWithString:@"bitcoin:1EXrR9YSEEXtFSYWjNnwrhyRhc4DoQHhzC"]; + if([[UIApplication sharedApplication] canOpenURL:targetURL]) + [[UIApplication sharedApplication] openURL:targetURL]; + else{ + [[UIPasteboard generalPasteboard] setString:@"1EXrR9YSEEXtFSYWjNnwrhyRhc4DoQHhzC"]; + UIAlertController* alert=[UIAlertController alertControllerWithTitle:@"" message:@"BTC address 1EXrR9YSEEXtFSYWjNnwrhyRhc4DoQHhzC; have been copied in your pasteboard" preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"OKay" style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController: alert animated:YES completion:nil]; + } + }]]; + [alert addAction:[UIAlertAction actionWithTitle:[self localized:@"ALIPAY"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* _Nonnull action) + { + NSURL *targetURL = [NSURL URLWithString:@"alipayqr://platformapi/startapp?saId=10000007&qrcode=https%3A%2F%2Fqr.alipay.com%2Faex04760kwfblpiaho9mg00"]; + if([[UIApplication sharedApplication] canOpenURL:targetURL]) + [[UIApplication sharedApplication] openURL:targetURL]; + else + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://qr.alipay.com/aex04760kwfblpiaho9mg00"]]; + }]]; + [alert addAction:[UIAlertAction actionWithTitle:[self localized:@"PAYPAL"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* _Nonnull action) + {[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=W25D7EKNG9JNQ&lc=C2&item_name=Donation&button_subtype=services"]]; + }]]; + [alert addAction:[UIAlertAction actionWithTitle:[self localized:@"CANCEL"] style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController: alert animated:YES completion:nil]; } - (void)viewSource:(id)arg { diff --git a/CyDelete/Makefile b/CyDelete/Makefile index 38db991..8c82196 100644 --- a/CyDelete/Makefile +++ b/CyDelete/Makefile @@ -1,6 +1,6 @@ ARCHS = armv7 arm64 -TARGET = iphone:8.1 +TARGET = iphone include theos/makefiles/common.mk diff --git a/CyDelete/Resources/CyDelete.plist b/CyDelete/Resources/CyDelete.plist index c283f4a..e7bb2de 100644 --- a/CyDelete/Resources/CyDelete.plist +++ b/CyDelete/Resources/CyDelete.plist @@ -68,7 +68,15 @@ action - ryanDonate: + donate: + cell + PSButtonCell + label + DONATE + + + action + donate2: cell PSButtonCell label @@ -84,6 +92,6 @@ title - CyDelete8 + CyDelete9 diff --git a/CyDelete/Resources/Pangu.png b/CyDelete/Resources/Pangu.png index 7fb8c85..fc46f34 100644 Binary files a/CyDelete/Resources/Pangu.png and b/CyDelete/Resources/Pangu.png differ diff --git a/CyDelete/Resources/en.lproj/Localizable.strings b/CyDelete/Resources/en.lproj/Localizable.strings index 8bd5e9f..6f361ae 100755 --- a/CyDelete/Resources/en.lproj/Localizable.strings +++ b/CyDelete/Resources/en.lproj/Localizable.strings @@ -3,7 +3,7 @@ DONATE - Donate via PayPal + Donate NON_CYDIA_DEL Non-Cydia Deletion NON_CYDIA_DEL_TEXT @@ -18,12 +18,21 @@ Settings NO_DRM_DONATE_COPYRIGHT -There is no DRM protection on this application but please help support future development (my coffee fund) by donating via PayPal. +There is no DRM protection on this application but please help support future development (my coffee fund) by donating. +CyDelete9 © 2016 Pal Lockheart CyDelete8 © 2014 Ryan Burke CyDelete © 2009-2011 Dustin L. Howett Released under the GPLv3 Licence. SOURCE_CODE Source Code + PAYPAL + PayPal + BITCOIN + Bitcoin + ALIPAY + Alipay + CANCEL + Cancel diff --git a/CyDelete/Resources/pt_PT.lproj/Localizable.strings b/CyDelete/Resources/pt_PT.lproj/Localizable.strings index 54de1bf..e82c52c 100644 --- a/CyDelete/Resources/pt_PT.lproj/Localizable.strings +++ b/CyDelete/Resources/pt_PT.lproj/Localizable.strings @@ -3,7 +3,7 @@ DONATE - Doar via PayPal + Doar NON_CYDIA_DEL Eliminação não Cydia NON_CYDIA_DEL_TEXT @@ -18,8 +18,9 @@ Definições NO_DRM_DONATE_COPYRIGHT -Não há protecção DRM nesta aplicação, por favor apoie o desenvolvimento futuro (o meu fundo para café) ao doar via PayPal. +Não há protecção DRM nesta aplicação, por favor apoie o desenvolvimento futuro (o meu fundo para café) ao doar. +CyDelete9 © 2016 Pal Lockhart CyDelete8 © 2014 Ryan Burke CyDelete © 2009-2011 Dustin L. Howett Disponibilizado sob licença GPLv3. diff --git a/CyDelete/Resources/zh_CN.lproj/Localizable.strings b/CyDelete/Resources/zh_CN.lproj/Localizable.strings index 0cbdc34..66d1cf2 100755 --- a/CyDelete/Resources/zh_CN.lproj/Localizable.strings +++ b/CyDelete/Resources/zh_CN.lproj/Localizable.strings @@ -3,7 +3,7 @@ DONATE - 通过PayPal捐助 + 捐助 NON_CYDIA_DEL 非Cydia卸载 NON_CYDIA_DEL_TEXT @@ -12,5 +12,27 @@ 受保护的程序 PROTECTED_WARNING 卸载这两个应用程序将会导致安装软件包时无图形界面,因此不推荐这样做。 + ENABLED + 启用 + SETTINGS_TITLE + 设置 + NO_DRM_DONATE_COPYRIGHT + +本程序未做版权保护,若希望作者有动力继续更新,还请捐杯咖啡钱。 + +CyDelete9 © 2016 路痴 +CyDelete8 © 2014 Ryan Burke +CyDelete © 2009-2011 Dustin L. Howett +在GPLv3协议下发布. + SOURCE_CODE + 源代码 + PAYPAL + 贝宝 + BITCOIN + 比特币 + ALIPAY + 支付宝 + CANCEL + 取消 diff --git a/CyDelete/theos b/CyDelete/theos index e30945d..11eaf40 120000 --- a/CyDelete/theos +++ b/CyDelete/theos @@ -1 +1 @@ -/opt/theos \ No newline at end of file +../theos \ No newline at end of file diff --git a/Makefile b/Makefile index d7e3a3b..1a4cd01 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ ARCHS = armv7 arm64 -TARGET = iphone:8.1 +TARGET = iphone include theos/makefiles/common.mk @@ -12,4 +12,4 @@ SUBPROJECTS += setuid CyDelete include $(THEOS_MAKE_PATH)/aggregate.mk after-install:: - install.exec "killall -9 SpringBoard" + install.exec "killall backboardd" diff --git a/README.md b/README.md index fc49847..83cd569 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ CyDelete ========= -The original mobile substrate CyDelete tweak created by @DHowett updated for iOS 7 and 8. +A mobile substrate tweak to uninstall applications from the homescreen that have been installed using Cydia. + +### Contributors +CyDelete - [Dustin Howett ](https://github.com/DHowett) +CyDelete 7 & 8 - [Ryan Burke](https://github.com/ryanb93) +CyDelete 9 - [Pal Lockhart](https://github.com/palxex) \ No newline at end of file diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index aa6ec47..64797c5 100755 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,13 +1,13 @@ Package: com.ryanburke.cydelete -Name: CyDelete8 -Depends: firmware (>=7.0), mobilesubstrate, preferenceloader, apt, bash +Name: CyDelete9 +Depends: firmware (>=9.0), mobilesubstrate, preferenceloader, apt, bash Conflicts: net.howett.cydelete, com.sosiphone.cydeletefr -Version: 1.0.2 +Version: 1.1.0 Architecture: iphoneos-arm -Description: Allows you to uninstall applications installed via Cydia from the Springboard just like AppStore applications. Just hold an icon down and tap on the X and the app will be uninstalled! This application is a new branch of the original CyDelete, created by @DHowett, bringing new support for iOS 8. Supports iOS 7 and 8. -Maintainer: Ryan Burke -Author: Ryan Burke +Description: Allows you to uninstall applications installed via Cydia from the Springboard just like AppStore applications. Just hold an icon down and tap on the X and the app will be uninstalled! This application is a new branch of the original CyDelete which created by @DHowett and ported to iOS8 by Ryan Burke, bringing new support for iOS 9.3. Supports iOS 7/8/9. +Maintainer: Pal Lockheart +Author: Pal Lockheart Section: Tweaks Depiction: http://moreinfo.thebigboss.org/moreinfo/depiction.php?file=cydelete7Dp -dev: ryanb93 +dev: palxex Tag: purpose::extension, role::enduser \ No newline at end of file diff --git a/layout/DEBIAN/postinst b/layout/DEBIAN/postinst new file mode 100755 index 0000000..b4b37dc --- /dev/null +++ b/layout/DEBIAN/postinst @@ -0,0 +1,6 @@ +#!/bin/bash +if [[ -e /usr/libexec/cydelete/setuid ]]; then + chmod 4755 /usr/libexec/cydelete/setuid + chown root:wheel /usr/libexec/cydelete/setuid +fi +exit 0 \ No newline at end of file diff --git a/setuid/Makefile b/setuid/Makefile index 2035300..d85dd2c 100644 --- a/setuid/Makefile +++ b/setuid/Makefile @@ -6,7 +6,3 @@ ARCHS = armv7 arm64 include ../theos/makefiles/common.mk include ../theos/makefiles/tool.mk - -after-setuid-stage:: - sudo chmod 4755 $(FW_STAGING_DIR)/usr/libexec/cydelete/setuid - sudo chown root:wheel $(FW_STAGING_DIR)/usr/libexec/cydelete/setuid diff --git a/theos b/theos index e30945d..11eaf40 120000 --- a/theos +++ b/theos @@ -1 +1 @@ -/opt/theos \ No newline at end of file +../theos \ No newline at end of file