X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/2e9123cb835e70b48f8eb4b72520e2ef5cbe92ec..740b712de9e2b43b52af962810595303c935c688:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index 999a708f..0b4b56e3 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -125,8 +125,6 @@ extern "C" { #include "SDURLCache/SDURLCache.h" #include "substrate.h" - -#include "Version.h" /* }}} */ /* Profiler {{{ */ @@ -208,6 +206,35 @@ void PrintTimes() { while (false); \ [_pool release]; +#define Cydia_ CYDIA_VERSION + +#define lprintf(args...) fprintf(stderr, args) + +#define ForRelease 1 +#define TraceLogging (1 && !ForRelease) +#define HistogramInsertionSort (!ForRelease ? 0 : 0) +#define ProfileTimes (0 && !ForRelease) +#define ForSaurik (0 && !ForRelease) +#define LogBrowser (0 && !ForRelease) +#define TrackResize (0 && !ForRelease) +#define ManualRefresh (1 && !ForRelease) +#define ShowInternals (0 && !ForRelease) +#define AlwaysReload (0 && !ForRelease) +#define TryIndexedCollation (0 && !ForRelease) + +#if !TraceLogging +#undef _trace +#define _trace(args...) +#endif + +#if !ProfileTimes +#undef _profile +#define _profile(name) { +#undef _end +#define _end } +#define PrintTimes() do {} while (false) +#endif + // Hash Functions/Structures {{{ extern "C" uint32_t hashlittle(const void *key, size_t length, uint32_t initval = 0); @@ -293,7 +320,9 @@ static _finline void UpdateExternalStatus(uint64_t newStatus) { NSDate *future([NSDate distantFuture]); NSString *mode([loop currentMode] ?: NSDefaultRunLoopMode); +_trace(); while (!stopped && [loop runMode:mode beforeDate:future]); +_trace(); return [context count] == 0 ? nil : [context objectAtIndex:0]; } @@ -360,33 +389,6 @@ static const NSStringCompareOptions MatchCompareOptions_ = NSLiteralSearch | NSC static const NSStringCompareOptions LaxCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSCaseInsensitiveSearch; static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering; -#define lprintf(args...) fprintf(stderr, args) - -#define ForRelease 1 -#define TraceLogging (1 && !ForRelease) -#define HistogramInsertionSort (!ForRelease ? 0 : 0) -#define ProfileTimes (0 && !ForRelease) -#define ForSaurik (0 && !ForRelease) -#define LogBrowser (0 && !ForRelease) -#define TrackResize (0 && !ForRelease) -#define ManualRefresh (1 && !ForRelease) -#define ShowInternals (0 && !ForRelease) -#define AlwaysReload (0 && !ForRelease) -#define TryIndexedCollation (0 && !ForRelease) - -#if !TraceLogging -#undef _trace -#define _trace(args...) -#endif - -#if !ProfileTimes -#undef _profile -#define _profile(name) { -#undef _end -#define _end } -#define PrintTimes() do {} while (false) -#endif - /* Radix Sort {{{ */ typedef uint32_t (*SKRadixFunction)(id, void *); @@ -1028,7 +1030,6 @@ static UIColor *InstallingColor_; static UIColor *RemovingColor_; static NSString *App_; -static NSString *Home_; static BOOL Advanced_; static BOOL Ignored_; @@ -1066,6 +1067,14 @@ static time_t now_; bool IsWildcat_; static CGFloat ScreenScale_; +static NSString *Idiom_; + +static NSMutableSet *CydiaHosts_; + +static NSString *kCydiaProgressEventTypeError = @"Error"; +static NSString *kCydiaProgressEventTypeInformation = @"Information"; +static NSString *kCydiaProgressEventTypeStatus = @"Status"; +static NSString *kCydiaProgressEventTypeWarning = @"Warning"; /* }}} */ /* Display Helpers {{{ */ @@ -1168,6 +1177,7 @@ bool isSectionVisible(NSString *section) { - (CYViewController *) pageForPackage:(NSString *)name; - (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item; - (void) reloadDataWithInvocation:(NSInvocation *)invocation; +- (void) addCydiaHost:(NSString *)host; @end /* }}} */ @@ -1210,6 +1220,7 @@ bool isSectionVisible(NSString *section) { @protocol ProgressDelegate - (void) addProgressEvent:(CydiaProgressEvent *)event; - (void) setProgressPercent:(NSNumber *)percent; +- (void) setProgressStatus:(NSDictionary *)status; - (void) setProgressCancellable:(NSNumber *)cancellable; - (bool) isProgressCancelled; - (void) setTitle:(NSString *)title; @@ -1247,7 +1258,7 @@ class Status : virtual void Fetch(pkgAcquire::ItemDesc &item) { NSString *name([NSString stringWithUTF8String:item.ShortDesc.c_str()]); - CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithFormat:UCLocalize("DOWNLOADING_"), name] ofType:@"STATUS" forItem:item]); + CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithFormat:UCLocalize("DOWNLOADING_"), name] ofType:kCydiaProgressEventTypeStatus forItem:item]); [delegate_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES]; } @@ -1265,19 +1276,26 @@ class Status : if (error.empty()) return; - CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:error.c_str()] ofType:@"ERROR" forItem:item]); + CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:error.c_str()] ofType:kCydiaProgressEventTypeError forItem:item]); [delegate_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES]; } virtual bool Pulse(pkgAcquire *Owner) { bool value = pkgAcquireStatus::Pulse(Owner); - float percent( + double percent( double(CurrentBytes + CurrentItems) / double(TotalBytes + TotalItems) ); - [delegate_ performSelectorOnMainThread:@selector(setProgressPercent:) withObject:[NSNumber numberWithFloat:percent] waitUntilDone:YES]; + [delegate_ performSelectorOnMainThread:@selector(setProgressStatus:) withObject:[NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithDouble:percent], @"Percent", + + [NSNumber numberWithDouble:CurrentBytes], @"Current", + [NSNumber numberWithDouble:TotalBytes], @"Total", + [NSNumber numberWithDouble:CurrentCPS], @"Speed", + nil] waitUntilDone:YES]; + if (value && ![delegate_ isProgressCancelled]) return true; else { @@ -1298,6 +1316,7 @@ class Status : virtual void Stop() { pkgAcquireStatus::Stop(); [delegate_ performSelectorOnMainThread:@selector(setProgressCancellable:) withObject:[NSNumber numberWithBool:NO] waitUntilDone:YES]; + [delegate_ performSelectorOnMainThread:@selector(setProgressStatus:) withObject:nil waitUntilDone:YES]; } }; /* }}} */ @@ -1477,9 +1496,9 @@ typedef std::map< unsigned long, _H > SourceMap; if (value != nil) { NSString *mode(nil); { NSString *type([self type]); - if ([type isEqualToString:@"ERROR"]) + if ([type isEqualToString:kCydiaProgressEventTypeError]) mode = UCLocalize("ERROR"); - else if ([type isEqualToString:@"WARNING"]) + else if ([type isEqualToString:kCydiaProgressEventTypeWarning]) mode = UCLocalize("WARNING"); } @@ -1629,12 +1648,12 @@ static void PackageImport(const void *key, const void *value, void *context) { CYString type_; CYString version_; - NSString *host_; - NSString *authority_; + _H host_; + _H authority_; CYString defaultIcon_; - NSDictionary *record_; + _H record_; BOOL trusted_; } @@ -1679,20 +1698,9 @@ static void PackageImport(const void *key, const void *value, void *context) { version_.clear(); defaultIcon_.clear(); - if (record_ != nil) { - [record_ release]; - record_ = nil; - } - - if (host_ != nil) { - [host_ release]; - host_ = nil; - } - - if (authority_ != nil) { - [authority_ release]; - authority_ = nil; - } + record_ = nil; + host_ = nil; + authority_ = nil; } - (void) dealloc { @@ -1770,22 +1778,18 @@ static void PackageImport(const void *key, const void *value, void *context) { } record_ = [Sources_ objectForKey:[self key]]; - if (record_ != nil) - record_ = [record_ retain]; NSURL *url([NSURL URLWithString:uri_]); host_ = [url host]; if (host_ != nil) - host_ = [[host_ lowercaseString] retain]; + host_ = [host_ lowercaseString]; if (host_ != nil) - authority_ = host_; + // XXX: this is due to a bug in _H<> + authority_ = (id) host_; else authority_ = [url path]; - - if (authority_ != nil) - authority_ = [authority_ retain]; } - (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool { @@ -1854,7 +1858,7 @@ static void PackageImport(const void *key, const void *value, void *context) { } - (NSString *) name { - return origin_.empty() ? authority_ : origin_; + return origin_.empty() ? (id) authority_ : origin_; } - (NSString *) description { @@ -1862,7 +1866,7 @@ static void PackageImport(const void *key, const void *value, void *context) { } - (NSString *) label { - return label_.empty() ? authority_ : label_; + return label_.empty() ? (id) authority_ : label_; } - (NSString *) origin { @@ -2366,13 +2370,16 @@ struct PackageNameOrdering : @"purposes", @"relations", @"section", + @"selection", @"shortDescription", @"shortSection", @"simpleSection", @"size", @"source", @"sponsor", + @"state", @"support", + @"tags", @"warnings", nil]; } @@ -2921,6 +2928,54 @@ struct PackageNameOrdering : return files; } +- (NSString *) state { +@synchronized (database_) { + if ([database_ era] != era_ || file_.end()) + return nil; + + switch (iterator_->CurrentState) { + case pkgCache::State::NotInstalled: + return @"NotInstalled"; + case pkgCache::State::UnPacked: + return @"UnPacked"; + case pkgCache::State::HalfConfigured: + return @"HalfConfigured"; + case pkgCache::State::HalfInstalled: + return @"HalfInstalled"; + case pkgCache::State::ConfigFiles: + return @"ConfigFiles"; + case pkgCache::State::Installed: + return @"Installed"; + case pkgCache::State::TriggersAwaited: + return @"TriggersAwaited"; + case pkgCache::State::TriggersPending: + return @"TriggersPending"; + } + + return (NSString *) [NSNull null]; +} } + +- (NSString *) selection { +@synchronized (database_) { + if ([database_ era] != era_ || file_.end()) + return nil; + + switch (iterator_->SelectedState) { + case pkgCache::State::Unknown: + return @"Unknown"; + case pkgCache::State::Install: + return @"Install"; + case pkgCache::State::Hold: + return @"Hold"; + case pkgCache::State::DeInstall: + return @"DeInstall"; + case pkgCache::State::Purge: + return @"Purge"; + } + + return (NSString *) [NSNull null]; +} } + - (NSArray *) warnings { NSMutableArray *warnings([NSMutableArray arrayWithCapacity:4]); const char *name(iterator_.Name()); @@ -3059,6 +3114,10 @@ struct PackageNameOrdering : _assert(false); } +- (NSArray *) tags { + return tags_; +} + - (BOOL) hasTag:(NSString *)tag { return tags_ == nil ? NO : [tags_ containsObject:tag]; } @@ -3382,11 +3441,17 @@ static NSString *Warning_; size_t size(line.size()); lprintf("S:%s\n", data); - if (conffile_r(data, size)) + if (conffile_r(data, size)) { + // status: /fail : conffile-prompt : '/fail' '/fail.dpkg-new' 1 1 [delegate_ performSelectorOnMainThread:@selector(setConfigurationData:) withObject:conffile_r[1] waitUntilDone:YES]; - else if (strncmp(data, "status: ", 8) == 0) { - CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:(data + 8)] ofType:@"STATUS"]); - [progress_ performSelectorOnMainThread:@selector(addProgressEvent) withObject:event waitUntilDone:YES]; + } else if (strncmp(data, "status: ", 8) == 0) { + // status: : {unpacked,half-configured,installed} + CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:(data + 8)] ofType:kCydiaProgressEventTypeStatus]); + [progress_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES]; + } else if (strncmp(data, "processing: ", 12) == 0) { + // processing: configure: config-test + CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:(data + 12)] ofType:kCydiaProgressEventTypeStatus]); + [progress_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES]; } else if (pmstatus_r(data, size)) { std::string type([pmstatus_r[1] UTF8String]); @@ -3400,10 +3465,10 @@ static NSString *Warning_; NSString *string = pmstatus_r[4]; if (type == "pmerror") { - CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:string ofType:@"ERROR" forPackage:package]); + CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:string ofType:kCydiaProgressEventTypeError forPackage:package]); [progress_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES]; } else if (type == "pmstatus") { - CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:string ofType:@"STATUS" forPackage:package]); + CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:string ofType:kCydiaProgressEventTypeStatus forPackage:package]); [progress_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES]; } else if (type == "pmconffile") [delegate_ performSelectorOnMainThread:@selector(setConfigurationData:) withObject:string waitUntilDone:YES]; @@ -3424,7 +3489,7 @@ static NSString *Warning_; while (std::getline(is, line)) { lprintf("O:%s\n", line.c_str()); - CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:line.c_str()] ofType:@"INFORMATION"]); + CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:line.c_str()] ofType:kCydiaProgressEventTypeInformation]); [progress_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES]; } @@ -3561,7 +3626,7 @@ static NSString *Warning_; lprintf("%c:[%s]\n", warning ? 'W' : 'E', error.c_str()); - [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:error.c_str()] ofType:(warning ? @"WARNING" : @"ERROR")] forTask:title]; + [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:error.c_str()] ofType:(warning ? kCydiaProgressEventTypeWarning : kCydiaProgressEventTypeError)] forTask:title]; } return fatal; @@ -3628,7 +3693,7 @@ static NSString *Warning_; // else if (error == "Malformed Status line") // else if (error == "The list of sources could not be read.") else { - [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:error.c_str()] ofType:(warning ? @"WARNING" : @"ERROR")] forTask:title]; + [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:error.c_str()] ofType:(warning ? kCydiaProgressEventTypeWarning : kCydiaProgressEventTypeError)] forTask:title]; return; } @@ -3653,7 +3718,7 @@ static NSString *Warning_; return; if (cache_->DelCount() != 0 || cache_->InstCount() != 0) { - [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:UCLocalize("COUNTS_NONZERO_EX") ofType:@"ERROR"] forTask:title]; + [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:UCLocalize("COUNTS_NONZERO_EX") ofType:kCydiaProgressEventTypeError] forTask:title]; return; } @@ -3665,7 +3730,7 @@ static NSString *Warning_; return; if (cache_->BrokenCount() != 0) { - [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:UCLocalize("STILL_BROKEN_EX") ofType:@"ERROR"] forTask:title]; + [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:UCLocalize("STILL_BROKEN_EX") ofType:kCydiaProgressEventTypeError] forTask:title]; return; } @@ -4043,17 +4108,7 @@ static NSString *Warning_; } - (NSString *) idiom { - UIDevice *device([UIDevice currentDevice]); - if (![device respondsToSelector:@selector(userInterfaceIdiom)]) - return @"iphone"; - - UIUserInterfaceIdiom idiom([device userInterfaceIdiom]); - if (idiom == UIUserInterfaceIdiomPhone) - return @"iphone"; - else if (idiom == UIUserInterfaceIdiomPad) - return @"ipad"; - else - return @"unknown"; + return (id) Idiom_ ?: [NSNull null]; } - (NSString *) plmn { @@ -4082,6 +4137,8 @@ static NSString *Warning_; + (NSString *) webScriptNameForSelector:(SEL)selector { if (false); + else if (selector == @selector(addCydiaHost:)) + return @"addCydiaHost"; else if (selector == @selector(addTrivialSource:)) return @"addTrivialSource"; else if (selector == @selector(close)) @@ -4108,12 +4165,24 @@ static NSString *Warning_; return @"refreshSources"; else if (selector == @selector(removeButton)) return @"removeButton"; + else if (selector == @selector(substitutePackageNames:)) + return @"substitutePackageNames"; else if (selector == @selector(scrollToBottom:)) return @"scrollToBottom"; + else if (selector == @selector(setAllowsNavigationAction:)) + return @"setAllowsNavigationAction"; else if (selector == @selector(setButtonImage:withStyle:toFunction:)) return @"setButtonImage"; else if (selector == @selector(setButtonTitle:withStyle:toFunction:)) return @"setButtonTitle"; + else if (selector == @selector(setHidesBackButton:)) + return @"setHidesBackButton"; + else if (selector == @selector(setHidesNavigationBar:)) + return @"setHidesNavigationBar"; + else if (selector == @selector(setNavigationBarStyle:)) + return @"setNavigationBarStyle"; + else if (selector == @selector(setNavigationBarTintRed:green:blue:alpha:)) + return @"setNavigationBarTintColor"; else if (selector == @selector(setPopupHook:)) return @"setPopupHook"; else if (selector == @selector(setToken:)) @@ -4170,6 +4239,10 @@ static NSString *Warning_; return [NSString stringWithCString:value]; } +- (void) addCydiaHost:(NSString *)host { + [delegate_ performSelectorOnMainThread:@selector(addCydiaHost:) withObject:host waitUntilDone:NO]; +} + - (void) addTrivialSource:(NSString *)href { [delegate_ performSelectorOnMainThread:@selector(addTrivialSource:) withObject:href waitUntilDone:NO]; } @@ -4266,6 +4339,17 @@ static NSString *Warning_; [delegate_ performSelectorOnMainThread:@selector(installPackages:) withObject:packages waitUntilDone:NO]; } +- (NSString *) substitutePackageNames:(NSString *)message { + NSMutableArray *words([[message componentsSeparatedByString:@" "] mutableCopy]); + for (size_t i(0), e([words count]); i != e; ++i) { + NSString *word([words objectAtIndex:i]); + if (Package *package = [[Database sharedInstance] packageWithName:word]) + [words replaceObjectAtIndex:i withObject:[package name]]; + } + + return [words componentsJoinedByString:@" "]; +} + - (void) removeButton { [indirect_ removeButton]; } @@ -4278,6 +4362,28 @@ static NSString *Warning_; [indirect_ setButtonTitle:button withStyle:style toFunction:function]; } +- (void) setAllowsNavigationAction:(NSString *)value { + [indirect_ performSelectorOnMainThread:@selector(setAllowsNavigationActionByNumber:) withObject:value waitUntilDone:NO]; +} + +- (void) setHidesBackButton:(NSString *)value { + [indirect_ performSelectorOnMainThread:@selector(setHidesBackButtonByNumber:) withObject:value waitUntilDone:NO]; +} + +- (void) setHidesNavigationBar:(NSString *)value { + [indirect_ performSelectorOnMainThread:@selector(setHidesNavigationBarByNumber:) withObject:value waitUntilDone:NO]; +} + +- (void) setNavigationBarStyle:(NSString *)value { + [indirect_ performSelectorOnMainThread:@selector(setNavigationBarStyle:) withObject:value waitUntilDone:NO]; +} + +- (void) setNavigationBarTintRed:(NSNumber *)red green:(NSNumber *)green blue:(NSNumber *)blue alpha:(NSNumber *)alpha { + float opacity(alpha == (id) [WebUndefined undefined] ? 1 : [alpha floatValue]); + UIColor *color([UIColor colorWithRed:[red floatValue] green:[green floatValue] blue:[blue floatValue] alpha:opacity]); + [indirect_ performSelectorOnMainThread:@selector(setNavigationBarTintColor:) withObject:color waitUntilDone:NO]; +} + - (void) _setToken:(NSString *)token { Token_ = token; @@ -4410,9 +4516,16 @@ static NSString *Warning_; } return self; } +// XXX: factor this out somewhere +- (UIColor *) groupTableViewBackgroundColor { + UIDevice *device([UIDevice currentDevice]); + bool iPad([device respondsToSelector:@selector(userInterfaceIdiom)] && [device userInterfaceIdiom] == UIUserInterfaceIdiomPad); + return iPad ? [UIColor colorWithRed:0.821 green:0.834 blue:0.860 alpha:1] : [UIColor groupTableViewBackgroundColor]; +} + - (void) loadView { [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - [[self view] setBackgroundColor:[UIColor pinStripeColor]]; + [[self view] setBackgroundColor:[self groupTableViewBackgroundColor]]; indicator_ = [[[CYLoadingIndicator alloc] initWithFrame:[[self view] bounds]] autorelease]; [indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; @@ -4456,47 +4569,28 @@ static NSString *Warning_; return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://url/%@", [[[webview_ request] URL] absoluteString]]]; } -- (void) setHeaders:(NSDictionary *)headers forHost:(NSString *)host { -} - - (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { [super webView:view didClearWindowObject:window forFrame:frame]; WebDataSource *source([frame dataSource]); NSURLResponse *response([source response]); - NSURL *url([response URL]); - NSString *scheme([url scheme]); - NSString *host([url host]); - - if ([response isKindOfClass:[NSHTTPURLResponse class]]) { - NSHTTPURLResponse *http((NSHTTPURLResponse *) response); - NSDictionary *headers([http allHeaderFields]); - [self setHeaders:headers forHost:host]; - } - if ( - [host isEqualToString:@"cydia.saurik.com"] || - [host hasSuffix:@".cydia.saurik.com"] || - [scheme isEqualToString:@"file"] - ) - [window setValue:cydia_ forKey:@"cydia"]; + if ([[[url scheme] lowercaseString] isEqualToString:@"https"]) + if ([CydiaHosts_ containsObject:[url host]]) + [window setValue:cydia_ forKey:@"cydia"]; } -- (void) _setMoreHeaders:(NSMutableURLRequest *)request { +- (NSURLRequest *) webView:(WebView *)view resource:(id)resource willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source { + NSMutableURLRequest *copy([[super webView:view resource:resource willSendRequest:request redirectResponse:response fromDataSource:source] mutableCopy]); + if (System_ != NULL) - [request setValue:System_ forHTTPHeaderField:@"X-System"]; + [copy setValue:System_ forHTTPHeaderField:@"X-System"]; if (Machine_ != NULL) - [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; + [copy setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; if (Token_ != nil) - [request setValue:Token_ forHTTPHeaderField:@"X-Cydia-Token"]; - if (Role_ != nil) - [request setValue:Role_ forHTTPHeaderField:@"X-Role"]; -} + [copy setValue:Token_ forHTTPHeaderField:@"X-Cydia-Token"]; -- (NSURLRequest *) webView:(WebView *)view resource:(id)resource willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source { - NSMutableURLRequest *copy([[super webView:view resource:resource willSendRequest:request redirectResponse:response fromDataSource:source] mutableCopy]); - [self _setMoreHeaders:copy]; return copy; } @@ -4831,7 +4925,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [NSNumber numberWithInteger:[database_ fetcher].PartialPresent()], @"resuming", nil]; - [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/confirm/", UI_]]]; + [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/confirm/", UI_]]]; [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] initWithTitle:UCLocalize("CANCEL") @@ -4878,7 +4972,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _transient id delegate_; bool running_; - float progress_; + float percent_; + + float current_; + float total_; + float speed_; _H events_; _H title_; @@ -4893,11 +4991,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { + (NSArray *) _attributeKeys { return [NSArray arrayWithObjects: + @"current", @"events", @"finish", - @"progress", + @"percent", @"running", + @"speed", @"title", + @"total", nil]; } @@ -4919,12 +5020,36 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { delegate_ = delegate; } -- (void) setProgress:(float)value { - progress_ = value; +- (void) setPercent:(float)value { + percent_ = value; +} + +- (NSNumber *) percent { + return [NSNumber numberWithFloat:percent_]; +} + +- (void) setCurrent:(float)value { + current_ = value; +} + +- (NSNumber *) current { + return [NSNumber numberWithFloat:current_]; +} + +- (void) setTotal:(float)value { + total_ = value; +} + +- (NSNumber *) total { + return [NSNumber numberWithFloat:total_]; +} + +- (void) setSpeed:(float)value { + speed_ = value; } -- (NSNumber *) progress { - return [NSNumber numberWithFloat:progress_]; +- (NSNumber *) speed { + return [NSNumber numberWithFloat:speed_]; } - (NSArray *) events { @@ -4991,6 +5116,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [super dealloc]; } +- (void) updateCancel { + [[self navigationItem] setLeftBarButtonItem:(cancel_ == 1 ? [[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("CANCEL") + style:UIBarButtonItemStylePlain + target:self + action:@selector(cancel) + ] autorelease] : nil)]; +} + - (id) initWithDatabase:(Database *)database delegate:(id)delegate { if ((self = [super init]) != nil) { database_ = database; @@ -5000,6 +5134,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { progress_ = [[[CydiaProgressData alloc] init] autorelease]; [progress_ setDelegate:self]; + + [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/progress/", UI_]]]; + + [scroller_ setBackgroundColor:[UIColor blackColor]]; + + [[self navigationItem] setHidesBackButton:YES]; + + [self updateCancel]; } return self; } @@ -5012,28 +5154,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self dispatchEvent:@"CydiaProgressUpdate"]; } -- (void) updateCancel { - [[self navigationItem] setLeftBarButtonItem:(cancel_ == 1 ? [[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("CANCEL") - style:UIBarButtonItemStylePlain - target:self - action:@selector(cancel) - ] autorelease] : nil)]; -} - - (void) viewWillAppear:(BOOL)animated { - if (![self hasLoaded]) { - [scroller_ setBackgroundColor:[UIColor blackColor]]; - [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/progress/", UI_]]]; - } - - [super viewDidAppear:animated]; - - [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack]; - - [[self navigationItem] setHidesBackButton:YES]; + if (![self hasLoaded]) + [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack]; - [self updateCancel]; + [super viewWillAppear:animated]; } - (void) close { @@ -5210,7 +5335,23 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) setProgressPercent:(NSNumber *)percent { - [progress_ setProgress:[percent floatValue]]; + [progress_ setPercent:[percent floatValue]]; + [self updateProgress]; +} + +- (void) setProgressStatus:(NSDictionary *)status { + if (status == nil) { + [progress_ setCurrent:0]; + [progress_ setTotal:0]; + [progress_ setSpeed:0]; + } else { + [progress_ setPercent:[[status objectForKey:@"Percent"] floatValue]]; + + [progress_ setCurrent:[[status objectForKey:@"Current"] floatValue]]; + [progress_ setTotal:[[status objectForKey:@"Total"] floatValue]]; + [progress_ setSpeed:[[status objectForKey:@"Speed"] floatValue]]; + } + [self updateProgress]; } @@ -5790,11 +5931,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { UIActionSheetDelegate > { _transient Database *database_; - Package *package_; - NSString *name_; + _H package_; + _H name_; bool commercial_; - NSMutableArray *buttons_; - UIBarButtonItem *button_; + _H buttons_; + _H button_; } - (id) initWithDatabase:(Database *)database forPackage:(NSString *)name; @@ -5803,22 +5944,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation CYPackageController -- (void) dealloc { - if (package_ != nil) - [package_ release]; - if (name_ != nil) - [name_ release]; - - [buttons_ release]; - - if (button_ != nil) - [button_ release]; - - [super dealloc]; -} - - (NSURL *) navigationURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@", name_]]; + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@", (id) name_]]; } /* XXX: this is not safe at all... localization of /fail/ */ @@ -5912,23 +6039,20 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (id) initWithDatabase:(Database *)database forPackage:(NSString *)name { if ((self = [super init]) != nil) { database_ = database; - buttons_ = [[NSMutableArray alloc] initWithCapacity:4]; - name_ = [[NSString alloc] initWithString:name]; - [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/package/#!/%@", UI_, name_]]]; + buttons_ = [NSMutableArray arrayWithCapacity:4]; + name_ = [NSString stringWithString:name]; + [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/package/%@", UI_, (id) name_]]]; } return self; } - (void) reloadData { - if (package_ != nil) - [package_ autorelease]; package_ = [database_ packageWithName:name_]; [buttons_ removeAllObjects]; if (package_ != nil) { - [package_ parse]; + [(Package *) package_ parse]; - package_ = [package_ retain]; commercial_ = [package_ isCommercial]; if ([package_ mode] != nil) @@ -5944,9 +6068,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [buttons_ addObject:UCLocalize("REMOVE")]; } - if (button_ != nil) - [button_ release]; - NSString *title; switch ([buttons_ count]) { case 0: title = nil; break; @@ -5954,12 +6075,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { default: title = UCLocalize("MODIFY"); break; } - button_ = [[UIBarButtonItem alloc] + button_ = [[[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:self action:@selector(customButtonClicked) - ]; + ] autorelease]; [super reloadData]; } @@ -6349,25 +6470,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation HomeController -+ (BOOL) shouldHideNavigationBar { - return NO; +- (id) init { + if ((self = [super init]) != nil) { + [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/home/", UI_]]]; + } return self; } - (NSURL *) navigationURL { return [NSURL URLWithString:@"cydia://home"]; } -- (void) _setMoreHeaders:(NSMutableURLRequest *)request { - [super _setMoreHeaders:request]; - - if (ChipID_ != nil) - [request setValue:ChipID_ forHTTPHeaderField:@"X-Chip-ID"]; - if (UniqueID_ != nil) - [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"]; - if (PLMN_ != nil) - [request setValue:PLMN_ forHTTPHeaderField:@"X-Carrier-ID"]; -} - - (void) aboutButtonClicked { UIAlertView *alert([[[UIAlertView alloc] init] autorelease]); @@ -6385,23 +6497,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [alert show]; } -- (void) viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - if ([[self class] shouldHideNavigationBar]) - [[self navigationController] setNavigationBarHidden:NO animated:animated]; -} - -- (void) viewWillAppear:(BOOL)animated { - if (![self hasLoaded]) - [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/home/", UI_]]]; - - [super viewWillAppear:animated]; - - if ([[self class] shouldHideNavigationBar]) - [[self navigationController] setNavigationBarHidden:YES animated:animated]; -} - - (void) viewDidLoad { [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] initWithTitle:UCLocalize("ABOUT") @@ -6423,15 +6518,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation ManageController -- (NSURL *) navigationURL { - return [NSURL URLWithString:@"cydia://manage"]; +- (id) init { + if ((self = [super init]) != nil) { + [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/manage/", UI_]]]; + } return self; } -- (void) viewWillAppear:(BOOL)animated { - if (![self hasLoaded]) - [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/manage/", UI_]]]; - - [super viewWillAppear:animated]; +- (NSURL *) navigationURL { + return [NSURL URLWithString:@"cydia://manage"]; } - (void) viewDidLoad { @@ -6777,6 +6871,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [refreshbar_ setProgress:[percent floatValue]]; } +- (void) setProgressStatus:(NSDictionary *)status { + if (status != nil) + [self setProgressPercent:[status objectForKey:@"Percent"]]; +} + - (void) setUpdateDelegate:(id)delegate { updatedelegate_ = delegate; } @@ -7053,7 +7152,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { /* Section Controller {{{ */ @interface SectionController : FilteredPackageListController { - NSString *section_; + _H section_; } - (id) initWithDatabase:(Database *)database section:(NSString *)section; @@ -7546,7 +7645,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @interface SearchController : FilteredPackageListController < UISearchBarDelegate > { - UISearchBar *search_; + _H search_; BOOL searchloaded_; } @@ -7559,7 +7658,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation SearchController - (void) dealloc { - [search_ release]; + [search_ setDelegate:nil]; [super dealloc]; } @@ -7588,7 +7687,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (id) initWithDatabase:(Database *)database { if ((self = [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil])) { - search_ = [[UISearchBar alloc] init]; + search_ = [[[UISearchBar alloc] init] autorelease]; + [search_ setDelegate:self]; } return self; } @@ -7608,7 +7708,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { textField = MSHookIvar(search_, "_searchField"); [textField setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin]; - [search_ setDelegate:self]; [textField setEnablesReturnKeyAutomatically:NO]; [[self navigationItem] setTitleView:textField]; } @@ -8288,8 +8387,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; if (UniqueID_ != nil) [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"]; - if (Role_ != nil) - [request setValue:Role_ forHTTPHeaderField:@"X-Role"]; return [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease]; } @@ -8804,6 +8901,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { ] autorelease]; [alert setContext:@"fixhalf"]; + [alert setNumberOfRows:2]; [alert show]; } else if (!Ignored_ && [essential_ count] != 0) { int count = [essential_ count]; @@ -9028,7 +9126,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) repairWithInvocation:(NSInvocation *)invocation { _trace(); - [self invokeNewProgress:invocation forController:nil withTitle:UCLocalize("REPAIRING")]; + [self invokeNewProgress:invocation forController:nil withTitle:@"REPAIRING"]; _trace(); } @@ -9054,7 +9152,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { fclose(file); - [self detachNewProgressSelector:@selector(update_) toTarget:self forController:nil title:UCLocalize("UPDATING_SOURCES")]; + [self detachNewProgressSelector:@selector(update_) toTarget:self forController:nil title:@"UPDATING_SOURCES"]; [self complete]; } @@ -9160,7 +9258,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) confirmWithNavigationController:(UINavigationController *)navigation { Queuing_ = false; ++locked_; - [self detachNewProgressSelector:@selector(perform) toTarget:database_ forController:navigation title:UCLocalize("RUNNING")]; + [self detachNewProgressSelector:@selector(perform) toTarget:database_ forController:navigation title:@"RUNNING"]; --locked_; [self complete]; } @@ -9270,6 +9368,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (BOOL) isSafeToSuspend { + if (locked_ != 0) { +#if !ForRelease + NSLog(@"isSafeToSuspend: locked_ != 0"); +#endif + return false; + } + // Use external process status API internally. // This is probably a really bad idea. // XXX: what is the point of this? does this solve anything at all? @@ -9280,7 +9385,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { notify_cancel(notify_token); } - return locked_ == 0 && status == 0; + if (status != 0) { +#if !ForRelease + NSLog(@"isSafeToSuspend: status != 0"); +#endif + return false; + } + +#if !ForRelease + NSLog(@"isSafeToSuspend: -> true"); +#endif + return true; } - (void) applicationSuspend:(__GSEvent *)event { @@ -9485,6 +9600,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { ] autorelease]; [alert setContext:@"conffile"]; + [alert setNumberOfRows:2]; [alert show]; } @@ -9544,11 +9660,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [tabbar_ setUpdateDelegate:self]; } +- (void) addCydiaHost:(NSString *)host { + [CydiaHosts_ addObject:host]; +} + - (void) applicationDidFinishLaunching:(id)unused { _trace(); if ([self respondsToSelector:@selector(setApplicationSupportsShakeToEdit:)]) [self setApplicationSupportsShakeToEdit:NO]; + [self addCydiaHost:[[NSURL URLWithString:CydiaURL(@"")] host]]; + [NSURLCache setSharedURLCache:[[[SDURLCache alloc] initWithMemoryCapacity:524288 diskCapacity:10485760 @@ -9796,11 +9918,22 @@ int main(int argc, char *argv[]) { _pooled else ScreenScale_ = 1; - NSMutableArray *parts([NSMutableArray arrayWithCapacity:2]); - if (ScreenScale_ > 1) - [parts addObject:@"@2x"]; - [parts addObject:(IsWildcat_ ? @"~ipad" : @"~iphone")]; - UI_ = CydiaURL([NSString stringWithFormat:@"ui/ios%@", [parts componentsJoinedByString:@""]]); + UIDevice *device([UIDevice currentDevice]); + if (![device respondsToSelector:@selector(userInterfaceIdiom)]) + Idiom_ = @"iphone"; + else { + UIUserInterfaceIdiom idiom([device userInterfaceIdiom]); + if (idiom == UIUserInterfaceIdiomPhone) + Idiom_ = @"iphone"; + else if (idiom == UIUserInterfaceIdiomPad) + Idiom_ = @"ipad"; + else + NSLog(@"unknown UIUserInterfaceIdiom!"); + } + + CydiaHosts_ = [NSMutableSet setWithCapacity:2]; + + UI_ = CydiaURL([NSString stringWithFormat:@"ui/ios~%@", Idiom_]); PackageName = reinterpret_cast(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname)))); @@ -9841,9 +9974,9 @@ int main(int argc, char *argv[]) { _pooled else { lang = [[Languages_ objectAtIndex:0] UTF8String]; setenv("LANG", lang, true); + std::setlocale(LC_ALL, lang); } - //std::setlocale(LC_ALL, lang); NSLog(@"Setting Language: %s", lang); /* }}} */ @@ -9874,7 +10007,6 @@ int main(int argc, char *argv[]) { _pooled /* }}} */ App_ = [[NSBundle mainBundle] bundlePath]; - Home_ = NSHomeDirectory(); Advanced_ = YES; setuid(0); @@ -10014,8 +10146,11 @@ int main(int argc, char *argv[]) { _pooled Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil]; #define MobileSubstrate_(name) \ - if (substrate && access("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", F_OK) == 0) \ - dlopen("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", RTLD_LAZY | RTLD_GLOBAL); + if (substrate && access("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", F_OK) == 0) { \ + void *handle(dlopen("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", RTLD_LAZY | RTLD_GLOBAL)); \ + if (handle == NULL) \ + NSLog(@"%s", dlerror()); \ + } MobileSubstrate_(Activator) MobileSubstrate_(libstatusbar) @@ -10030,7 +10165,7 @@ int main(int argc, char *argv[]) { _pooled if (access("/tmp/.cydia.fw", F_OK) == 0) { unlink("/tmp/.cydia.fw"); goto firmware; - } else if (access("/User", F_OK) != 0 || version < 2) { + } else if (access("/User", F_OK) != 0 || version < 4) { firmware: _trace(); system("/usr/libexec/cydia/firmware.sh");