]> git.saurik.com Git - cydia.git/blobdiff - MobileCydia.mm
Standardize [super reloadData] placement.
[cydia.git] / MobileCydia.mm
index ff1187939ee1da380500fce62bff22d75c452f9b..e278ab8605eea1614914794652904b319504d9a0 100644 (file)
@@ -1086,7 +1086,10 @@ bool IsWildcat_;
 static CGFloat ScreenScale_;
 static NSString *Idiom_;
 
-static NSMutableSet *CydiaHosts_;
+static NSMutableDictionary *SessionData_;
+static NSObject *HostConfig_;
+static NSMutableSet *BridgedHosts_;
+static NSMutableSet *PipelinedHosts_;
 
 static NSString *kCydiaProgressEventTypeError = @"Error";
 static NSString *kCydiaProgressEventTypeInformation = @"Information";
@@ -1194,7 +1197,6 @@ bool isSectionVisible(NSString *section) {
 - (CYViewController *) pageForPackage:(NSString *)name;
 - (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item;
 - (void) reloadDataWithInvocation:(NSInvocation *)invocation;
-- (void) addCydiaHost:(NSString *)host;
 @end
 /* }}} */
 
@@ -4208,8 +4210,10 @@ static NSMutableSet *Diversions_;
 
 + (NSString *) webScriptNameForSelector:(SEL)selector {
     if (false);
-    else if (selector == @selector(addCydiaHost:))
-        return @"addCydiaHost";
+    else if (selector == @selector(addBridgedHost:))
+        return @"addBridgedHost";
+    else if (selector == @selector(addPipelinedHost:scheme:))
+        return @"addPipelinedHost";
     else if (selector == @selector(addTrivialSource:))
         return @"addTrivialSource";
     else if (selector == @selector(close))
@@ -4230,14 +4234,20 @@ static NSMutableSet *Diversions_;
         return @"getInstalledPackages";
     else if (selector == @selector(getPackageById:))
         return @"getPackageById";
+    else if (selector == @selector(getSessionValue:))
+        return @"getSessionValue";
     else if (selector == @selector(installPackages:))
         return @"installPackages";
     else if (selector == @selector(localizedStringForKey:value:table:))
         return @"localize";
+    else if (selector == @selector(popViewController:))
+        return @"popViewController";
     else if (selector == @selector(refreshSources))
         return @"refreshSources";
     else if (selector == @selector(removeButton))
         return @"removeButton";
+    else if (selector == @selector(setSessionValue::))
+        return @"setSessionValue";
     else if (selector == @selector(substitutePackageNames:))
         return @"substitutePackageNames";
     else if (selector == @selector(scrollToBottom:))
@@ -4316,8 +4326,36 @@ static NSMutableSet *Diversions_;
     return [NSString stringWithCString:value];
 }
 
-- (void) addCydiaHost:(NSString *)host {
-    [delegate_ performSelectorOnMainThread:@selector(addCydiaHost:) withObject:host waitUntilDone:NO];
+- (id) getSessionValue:(NSString *)key {
+@synchronized (SessionData_) {
+    return [SessionData_ objectForKey:key];
+} }
+
+- (void) setSessionValue:(NSString *)key :(NSString *)value {
+@synchronized (SessionData_) {
+    if (value == (id) [WebUndefined undefined])
+        [SessionData_ removeObjectForKey:key];
+    else
+        [SessionData_ setObject:value forKey:key];
+} }
+
+- (void) addBridgedHost:(NSString *)host {
+@synchronized (HostConfig_) {
+    [BridgedHosts_ addObject:host];
+} }
+
+- (void) addPipelinedHost:(NSString *)host scheme:(NSString *)scheme {
+@synchronized (HostConfig_) {
+    if (scheme != (id) [WebUndefined undefined])
+        host = [NSString stringWithFormat:@"%@:%@", [scheme lowercaseString], host];
+
+    [PipelinedHosts_ addObject:host];
+} }
+
+- (void) popViewController:(NSNumber *)value {
+    if (value == (id) [WebUndefined undefined])
+        value = [NSNumber numberWithBool:YES];
+    [indirect_ performSelectorOnMainThread:@selector(popViewControllerWithNumber:) withObject:value waitUntilDone:NO];
 }
 
 - (void) addTrivialSource:(NSString *)href {
@@ -4651,9 +4689,11 @@ static NSMutableSet *Diversions_;
     NSURLResponse *response([source response]);
     NSURL *url([response URL]);
 
-    if ([[[url scheme] lowercaseString] isEqualToString:@"https"])
-        if ([CydiaHosts_ containsObject:[url host]])
-            [window setValue:cydia_ forKey:@"cydia"];
+    @synchronized (HostConfig_) {
+        if ([[[url scheme] lowercaseString] isEqualToString:@"https"])
+            if ([BridgedHosts_ containsObject:[url host]])
+                [window setValue:cydia_ forKey:@"cydia"];
+    }
 }
 
 - (NSURLRequest *) webView:(WebView *)view resource:(id)resource willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source {
@@ -5240,9 +5280,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) viewWillAppear:(BOOL)animated {
-    if (![self hasLoaded])
-        [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack];
-
+    [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack];
     [super viewWillAppear:animated];
 }
 
@@ -6131,6 +6169,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) reloadData {
+    [super reloadData];
+
     package_ = [database_ packageWithName:name_];
 
     [buttons_ removeAllObjects];
@@ -6166,8 +6206,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         target:self
         action:@selector(customButtonClicked)
     ] autorelease];
-
-    [super reloadData];
 }
 
 - (bool) isLoading {
@@ -7279,7 +7317,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     NSMutableArray *sections_;
     NSMutableArray *filtered_;
     UITableView *list_;
-    BOOL editing_;
 }
 
 - (id) initWithDatabase:(Database *)database;
@@ -7302,24 +7339,22 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) updateNavigationItem {
-    [[self navigationItem] setTitle:editing_ ? UCLocalize("SECTION_VISIBILITY") : UCLocalize("SECTIONS")];
+    [[self navigationItem] setTitle:[self isEditing] ? UCLocalize("SECTION_VISIBILITY") : UCLocalize("SECTIONS")];
     if ([sections_ count] == 0) {
         [[self navigationItem] setRightBarButtonItem:nil];
     } else {
         [[self navigationItem] setRightBarButtonItem:[[UIBarButtonItem alloc]
-            initWithBarButtonSystemItem:(editing_ ? UIBarButtonSystemItemDone : UIBarButtonSystemItemEdit)
+            initWithBarButtonSystemItem:([self isEditing] ? UIBarButtonSystemItemDone : UIBarButtonSystemItemEdit)
             target:self
             action:@selector(editButtonClicked)
         ] animated:([[self navigationItem] rightBarButtonItem] != nil)];
     }
 }
 
-- (BOOL) isEditing {
-    return editing_;
-}
+- (void) setEditing:(BOOL)editing animated:(BOOL)animated {
+    [super setEditing:editing animated:animated];
 
-- (void) setEditing:(BOOL)editing {
-    if ((editing_ = editing))
+    if (editing)
         [list_ reloadData];
     else
         [delegate_ updateData];
@@ -7334,16 +7369,27 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (void) viewWillDisappear:(BOOL)animated {
     [super viewWillDisappear:animated];
-    if (editing_) [self setEditing:NO];
+    if ([self isEditing]) [self setEditing:NO];
 }
 
 - (Section *) sectionAtIndexPath:(NSIndexPath *)indexPath {
-    Section *section = (editing_ ? [sections_ objectAtIndex:[indexPath row]] : ([indexPath row] == 0 ? nil : [filtered_ objectAtIndex:([indexPath row] - 1)]));
+    Section *section = nil;
+    int index = [indexPath row];
+    if (![self isEditing]) {
+        index -= 1; 
+        if (index >= 0)
+            section = [filtered_ objectAtIndex:index];
+    } else {
+        section = [sections_ objectAtIndex:index];
+    }
     return section;
 }
 
 - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
-    return editing_ ? [sections_ count] : [filtered_ count] + 1;
+    if ([self isEditing])
+        return [sections_ count];
+    else
+        return [filtered_ count] + 1;
 }
 
 /*- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
@@ -7357,13 +7403,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     if (cell == nil)
         cell = [[[SectionCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease];
 
-    [cell setSection:[self sectionAtIndexPath:indexPath] editing:editing_];
+    [cell setSection:[self sectionAtIndexPath:indexPath] editing:[self isEditing]];
 
     return cell;
 }
 
 - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
-    if (editing_)
+    if ([self isEditing])
         return;
 
     Section *section = [self sectionAtIndexPath:indexPath];
@@ -7464,7 +7510,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) editButtonClicked {
-    [self setEditing:(!editing_)];
+    [self setEditing:![self isEditing] animated:YES];
 }
 
 @end
@@ -7481,7 +7527,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     NSMutableArray *sections_;
     UITableView *list_;
     unsigned upgrades_;
-    BOOL hasSentFirstLoad_;
 }
 
 - (id) initWithDatabase:(Database *)database;
@@ -7502,21 +7547,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return [NSURL URLWithString:@"cydia://changes"];
 }
 
-- (void) viewWillAppear:(BOOL)animated {
-    // Loads after it appears, so don't load beforehand.
-    loaded_ = YES;
-    [super viewWillAppear:animated];
-}
-
 - (void) viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
-
-    if (!hasSentFirstLoad_) {
-        hasSentFirstLoad_ = YES;
-        [self performSelector:@selector(reloadData) withObject:nil afterDelay:0.0];
-    } else {
-        [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
-    }
+    [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
 }
 
 - (NSInteger) numberOfSectionsInTableView:(UITableView *)list {
@@ -7626,7 +7659,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     _trace();
 }
 
-- (void) reloadData {
+- (void) _reloadData {
 @synchronized (database_) {
     era_ = [database_ era];
     NSArray *packages = [database_ packages];
@@ -7724,6 +7757,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     PrintTimes();
 } }
 
+- (void) reloadData {
+    [super reloadData];
+    [self performSelector:@selector(_reloadData) withObject:nil afterDelay:0];
+}
+
 @end
 /* }}} */
 /* Search Controller {{{ */
@@ -7800,8 +7838,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (void) reloadData {
     [self setObject:[search_ text]];
-    [super reloadData];
     [self resetCursor];
+
+    [super reloadData];
 }
 
 - (void) didSelectPackage:(Package *)package {
@@ -8195,6 +8234,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [key_ release];
     key_ = [[source_ key] retain];
     [self setObject:source_];
+
     [[self navigationItem] setTitle:[source_ label]];
 
     [super reloadData];
@@ -8849,6 +8889,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
 - (void) reloadData {
     [super reloadData];
+
     [table_ reloadData];
 }
 
@@ -9745,16 +9786,14 @@ 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]];
+    @synchronized (HostConfig_) {
+        [BridgedHosts_ addObject:[[NSURL URLWithString:CydiaURL(@"")] host]];
+    }
 
     [NSURLCache setSharedURLCache:[[[SDURLCache alloc]
         initWithMemoryCapacity:524288
@@ -9813,6 +9852,21 @@ _trace();
 _trace();
 }
 
+- (NSArray *) defaultStartPages {
+    NSMutableArray *standard = [NSMutableArray array];
+    [standard addObject:[NSArray arrayWithObject:@"cydia://home"]];
+    [standard addObject:[NSArray arrayWithObject:@"cydia://sections"]];
+    [standard addObject:[NSArray arrayWithObject:@"cydia://changes"]];
+    if (!IsWildcat_) {
+        [standard addObject:[NSArray arrayWithObject:@"cydia://manage"]];
+    } else {
+        [standard addObject:[NSArray arrayWithObject:@"cydia://installed"]];
+        [standard addObject:[NSArray arrayWithObject:@"cydia://sources"]];
+    }
+    [standard addObject:[NSArray arrayWithObject:@"cydia://search"]];
+    return standard;
+}
+
 - (void) loadData {
 _trace();
     if (Role_ == nil) {
@@ -9830,42 +9884,48 @@ _trace();
 
     [self disemulate];
 
-    int selectedIndex = 0;
-    NSMutableArray *items = nil;
+    int savedIndex = [[Metadata_ objectForKey:@"InterfaceIndex"] intValue];
+    NSArray *saved = [[Metadata_ objectForKey:@"InterfaceState"] mutableCopy];
+    int standardIndex = 0;
+    NSArray *standard = [self defaultStartPages];
 
-    bool recently = false;
-    NSDate *closed([Metadata_ objectForKey:@"LastClosed"]);
-    if (closed != nil) {
+    BOOL valid = YES;
+
+    if (saved == nil)
+        valid = NO;
+
+    NSDate *closed = [Metadata_ objectForKey:@"LastClosed"];
+    if (valid && closed != nil) {
         NSTimeInterval interval([closed timeIntervalSinceNow]);
         // XXX: Is 15 minutes the optimal time here?
-        if (interval <= 0 && interval > -(15*60))
-            recently = true;
+        if (interval > 0 && interval <= -(15*60))
+            valid = NO;
     }
 
-    items = [[Metadata_ objectForKey:@"InterfaceState"] mutableCopy];
-    selectedIndex = [[Metadata_ objectForKey:@"InterfaceIndex"] intValue];
-
-    BOOL enough = YES;
-    for (NSArray *entry in items)
-        if ([entry count] <= 0)
-            enough = NO;
+    if (valid && [saved count] != [standard count])
+        valid = NO;
 
-    if (!recently || !items || !enough) {
-        selectedIndex = 0;
-        items = [NSMutableArray array];
-        [items addObject:[NSArray arrayWithObject:@"cydia://home"]];
-        [items addObject:[NSArray arrayWithObject:@"cydia://sections"]];
-        [items addObject:[NSArray arrayWithObject:@"cydia://changes"]];
-        if (!IsWildcat_) {
-            [items addObject:[NSArray arrayWithObject:@"cydia://manage"]];
-        } else {
-            [items addObject:[NSArray arrayWithObject:@"cydia://installed"]];
-            [items addObject:[NSArray arrayWithObject:@"cydia://sources"]];
+    if (valid) {
+        for (unsigned int i = 0; i < [standard count]; i++) {
+            NSArray *std = [standard objectAtIndex:i], *sav = [saved objectAtIndex:i];
+            // XXX: The "hasPrefix" sanity check here could be, in theory, fooled,
+            //      but it's good enough for now.
+            if ([sav count] == 0 || ![[sav objectAtIndex:0] hasPrefix:[std objectAtIndex:0]]) {
+                valid = NO;
+                break;
+            }
         }
-        [items addObject:[NSArray arrayWithObject:@"cydia://search"]];
     }
 
-    [tabbar_ setSelectedIndex:selectedIndex];
+    NSArray *items = nil;
+    if (valid) {
+        [tabbar_ setSelectedIndex:savedIndex];
+        items = saved;
+    } else {
+        [tabbar_ setSelectedIndex:standardIndex];
+        items = standard;
+    }
+
     for (unsigned int tab = 0; tab < [[tabbar_ viewControllers] count]; tab++) {
         NSArray *stack = [items objectAtIndex:tab];
         CYNavigationController *navigation = [[tabbar_ viewControllers] objectAtIndex:tab];
@@ -9986,6 +10046,27 @@ MSHook(void, UIApplication$_updateApplicationAccessibility, UIApplication *self,
     }
 }
 
+Class $NSURLConnection;
+
+MSHook(id, NSURLConnection$init$, NSURLConnection *self, SEL _cmd, NSURLRequest *request, id delegate, BOOL usesCache, int64_t maxContentLength, BOOL startImmediately, NSDictionary *connectionProperties) {
+    NSMutableURLRequest *copy([request mutableCopy]);
+
+    NSURL *url([copy URL]);
+    NSString *host([url host]);
+    NSString *scheme([[url scheme] lowercaseString]);
+
+    NSString *compound([NSString stringWithFormat:@"%@:%@", scheme, host]);
+
+    @synchronized (HostConfig_) {
+        if ([copy respondsToSelector:@selector(setHTTPShouldUsePipelining:)])
+            if ([PipelinedHosts_ containsObject:host] || [PipelinedHosts_ containsObject:compound])
+                [copy setHTTPShouldUsePipelining:YES];
+    }
+
+    if ((self = _NSURLConnection$init$(self, _cmd, copy, delegate, usesCache, maxContentLength, startImmediately, connectionProperties)) != nil) {
+    } return self;
+}
+
 int main(int argc, char *argv[]) { _pooled
     _trace();
 
@@ -10016,7 +10097,13 @@ int main(int argc, char *argv[]) { _pooled
             NSLog(@"unknown UIUserInterfaceIdiom!");
     }
 
-    CydiaHosts_ = [NSMutableSet setWithCapacity:2];
+    SessionData_ = [[NSMutableDictionary alloc] initWithCapacity:4];
+
+    HostConfig_ = [[NSObject alloc] init];
+    @synchronized (HostConfig_) {
+        BridgedHosts_ = [NSMutableSet setWithCapacity:4];
+        PipelinedHosts_ = [NSMutableSet setWithCapacity:4];
+    }
 
     UI_ = CydiaURL([NSString stringWithFormat:@"ui/ios~%@", Idiom_]);
 
@@ -10032,6 +10119,13 @@ int main(int argc, char *argv[]) { _pooled
         method_setImplementation(UIWebDocumentView$_setUIKitDelegate$, reinterpret_cast<IMP>(&$UIWebDocumentView$_setUIKitDelegate$));
     }
 
+    $NSURLConnection = objc_getClass("NSURLConnection");
+    Method NSURLConnection$init$(class_getInstanceMethod($NSURLConnection, @selector(_initWithRequest:delegate:usesCache:maxContentLength:startImmediately:connectionProperties:)));
+    if (NSURLConnection$init$ != NULL) {
+        _NSURLConnection$init$ = reinterpret_cast<id (*)(NSURLConnection *, SEL, NSURLRequest *, id, BOOL, int64_t, BOOL, NSDictionary *)>(method_getImplementation(NSURLConnection$init$));
+        method_setImplementation(NSURLConnection$init$, reinterpret_cast<IMP>(&$NSURLConnection$init$));
+    }
+
     $UIHardware = objc_getClass("UIHardware");
     Method UIHardware$_playSystemSound$(class_getClassMethod($UIHardware, @selector(_playSystemSound:)));
     if (UIHardware$_playSystemSound$ != NULL) {
@@ -10049,11 +10143,14 @@ int main(int argc, char *argv[]) { _pooled
     /* Set Locale {{{ */
     Locale_ = CFLocaleCopyCurrent();
     Languages_ = [NSLocale preferredLanguages];
+
     //CFStringRef locale(CFLocaleGetIdentifier(Locale_));
     //NSLog(@"%@", [Languages_ description]);
 
     const char *lang;
-    if (Languages_ == nil || [Languages_ count] == 0)
+    if (Locale_ != NULL)
+        lang = [(NSString *) CFLocaleGetIdentifier(Locale_) UTF8String];
+    else if (Languages_ == nil || [Languages_ count] == 0)
         // XXX: consider just setting to C and then falling through?
         lang = NULL;
     else {