]> git.saurik.com Git - cydia.git/blobdiff - MobileCydia.mm
Do not restart SpringBoard if symlink is damaged.
[cydia.git] / MobileCydia.mm
index 0dbc42d15d5f2a930166ebe137343a8d234365bd..7b1cff094e8cee64d48b8bb5613fbef901938906 100644 (file)
@@ -1,5 +1,5 @@
 /* Cydia - iPhone UIKit Front-End for Debian APT
- * Copyright (C) 2008-2013  Jay Freeman (saurik)
+ * Copyright (C) 2008-2014  Jay Freeman (saurik)
 */
 
 /* GNU General Public License, Version 3 {{{ */
@@ -812,6 +812,26 @@ inline float Interpolate(float begin, float end, float fraction) {
     return (end - begin) * fraction + begin;
 }
 
+static inline double Retina(double value) {
+    value *= ScreenScale_;
+    value = round(value);
+    value /= ScreenScale_;
+    return value;
+}
+
+static inline CGRect Retina(CGRect value) {
+    value.origin.x *= ScreenScale_;
+    value.origin.y *= ScreenScale_;
+    value.size.width *= ScreenScale_;
+    value.size.height *= ScreenScale_;
+    value = CGRectIntegral(value);
+    value.origin.x /= ScreenScale_;
+    value.origin.y /= ScreenScale_;
+    value.size.width /= ScreenScale_;
+    value.size.height /= ScreenScale_;
+    return value;
+}
+
 static _finline const char *StripVersion_(const char *version) {
     const char *colon(strchr(version, ':'));
     return colon == NULL ? version : colon + 1;
@@ -968,8 +988,8 @@ class CancelStatus :
         return false;
     }
 
-    virtual void IMSHit(pkgAcquire::ItemDesc &item) {
-        Done(item);
+    virtual void IMSHit(pkgAcquire::ItemDesc &desc) {
+        Done(desc);
     }
 
     virtual bool Pulse_(pkgAcquire *Owner) = 0;
@@ -1005,30 +1025,30 @@ class CydiaStatus :
         delegate_ = delegate;
     }
 
-    virtual void Fetch(pkgAcquire::ItemDesc &item) {
-        NSString *name([NSString stringWithUTF8String:item.ShortDesc.c_str()]);
-        CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithFormat:UCLocalize("DOWNLOADING_"), name] ofType:kCydiaProgressEventTypeStatus forItem:item]);
+    virtual void Fetch(pkgAcquire::ItemDesc &desc) {
+        NSString *name([NSString stringWithUTF8String:desc.ShortDesc.c_str()]);
+        CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithFormat:UCLocalize("DOWNLOADING_"), name] ofType:kCydiaProgressEventTypeStatus forItemDesc:desc]);
         [delegate_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES];
     }
 
-    virtual void Done(pkgAcquire::ItemDesc &item) {
-        NSString *name([NSString stringWithUTF8String:item.ShortDesc.c_str()]);
-        CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithFormat:Colon_, UCLocalize("DONE"), name] ofType:kCydiaProgressEventTypeStatus forItem:item]);
+    virtual void Done(pkgAcquire::ItemDesc &desc) {
+        NSString *name([NSString stringWithUTF8String:desc.ShortDesc.c_str()]);
+        CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithFormat:Colon_, UCLocalize("DONE"), name] ofType:kCydiaProgressEventTypeStatus forItemDesc:desc]);
         [delegate_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES];
     }
 
-    virtual void Fail(pkgAcquire::ItemDesc &item) {
+    virtual void Fail(pkgAcquire::ItemDesc &desc) {
         if (
-            item.Owner->Status == pkgAcquire::Item::StatIdle ||
-            item.Owner->Status == pkgAcquire::Item::StatDone
+            desc.Owner->Status == pkgAcquire::Item::StatIdle ||
+            desc.Owner->Status == pkgAcquire::Item::StatDone
         )
             return;
 
-        std::string &error(item.Owner->ErrorText);
+        std::string &error(desc.Owner->ErrorText);
         if (error.empty())
             return;
 
-        CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:error.c_str()] ofType:kCydiaProgressEventTypeError forItem:item]);
+        CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:error.c_str()] ofType:kCydiaProgressEventTypeError forItemDesc:desc]);
         [delegate_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES];
     }
 
@@ -1146,6 +1166,7 @@ class SourceStatus :
   private:
     _transient NSObject<FetchDelegate> *delegate_;
     _transient Database *database_;
+    std::set<std::string> fetches_;
 
   public:
     SourceStatus(NSObject<FetchDelegate> *delegate, Database *database) :
@@ -1154,30 +1175,74 @@ class SourceStatus :
     {
     }
 
-    void Set(bool fetch, pkgAcquire::ItemDesc &desc) {
-        desc.Owner->ID = 0;
-        [database_ setFetch:fetch forURI:desc.Owner->DescURI().c_str()];
+    void Set(bool fetch, const std::string &uri) {
+        if (fetch) {
+            if (!fetches_.insert(uri).second)
+                return;
+        } else {
+            if (fetches_.erase(uri) == 0)
+                return;
+        }
+
+        //printf("Set(%s, %s)\n", fetch ? "true" : "false", uri.c_str());
+        [database_ setFetch:fetch forURI:uri.c_str()];
+    }
+
+    _finline void Set(bool fetch, pkgAcquire::Item *item) {
+        /*unsigned long ID(fetch ? 1 : 0);
+        if (item->ID == ID)
+            return;
+        item->ID = ID;*/
+        Set(fetch, item->DescURI());
+    }
+
+    void Log(const char *tag, pkgAcquire::Item *item) {
+        //printf("%s(%s) S:%u Q:%u\n", tag, item->DescURI().c_str(), item->Status, item->QueueCounter);
     }
 
     virtual void Fetch(pkgAcquire::ItemDesc &desc) {
-        Set(true, desc);
+        Log("Fetch", desc.Owner);
+        Set(true, desc.Owner);
     }
 
     virtual void Done(pkgAcquire::ItemDesc &desc) {
-        Set(false, desc);
+        Log("Done", desc.Owner);
+        Set(false, desc.Owner);
     }
 
     virtual void Fail(pkgAcquire::ItemDesc &desc) {
-        Set(false, desc);
+        Log("Fail", desc.Owner);
+        Set(false, desc.Owner);
     }
 
     virtual bool Pulse_(pkgAcquire *Owner) {
-        for (pkgAcquire::ItemCIterator item = Owner->ItemsBegin(); item != Owner->ItemsEnd(); ++item)
-            if ((*item)->ID != 0);
-            else if ((*item)->Status == pkgAcquire::Item::StatIdle) {
-                (*item)->ID = 1;
-                [database_ setFetch:true forURI:(*item)->DescURI().c_str()];
-            } else (*item)->ID = 0;
+        std::set<std::string> fetches;
+        for (pkgAcquire::ItemCIterator item(Owner->ItemsBegin()); item != Owner->ItemsEnd(); ++item) {
+            bool fetch;
+            if ((*item)->QueueCounter == 0)
+                fetch = false;
+            else switch ((*item)->Status) {
+                case pkgAcquire::Item::StatFetching:
+                    fetches.insert((*item)->DescURI());
+                    fetch = true;
+                break;
+
+                default:
+                    fetch = false;
+                break;
+            }
+
+            Log(fetch ? "Pulse<true>" : "Pulse<false>", *item);
+            Set(fetch, *item);
+        }
+
+        std::vector<std::string> stops;
+        std::set_difference(fetches_.begin(), fetches_.end(), fetches.begin(), fetches.end(), std::back_insert_iterator<std::vector<std::string>>(stops));
+        for (std::vector<std::string>::const_iterator stop(stops.begin()); stop != stops.end(); ++stop) {
+            //printf("Stop(%s)\n", stop->c_str());
+            Set(false, *stop);
+        }
+
         return ![delegate_ isSourceCancelled];
     }
 
@@ -1200,10 +1265,10 @@ class SourceStatus :
     return event;
 }
 
-+ (CydiaProgressEvent *) eventWithMessage:(NSString *)message ofType:(NSString *)type forItem:(pkgAcquire::ItemDesc &)item {
++ (CydiaProgressEvent *) eventWithMessage:(NSString *)message ofType:(NSString *)type forItemDesc:(pkgAcquire::ItemDesc &)desc {
     CydiaProgressEvent *event([self eventWithMessage:message ofType:type]);
 
-    NSString *description([NSString stringWithUTF8String:item.Description.c_str()]);
+    NSString *description([NSString stringWithUTF8String:desc.Description.c_str()]);
     NSArray *fields([description componentsSeparatedByString:@" "]);
     [event setItem:fields];
 
@@ -1212,7 +1277,7 @@ class SourceStatus :
         [event setVersion:[fields objectAtIndex:3]];
     }
 
-    [event setURL:[NSString stringWithUTF8String:item.URI.c_str()]];
+    [event setURL:[NSString stringWithUTF8String:desc.URI.c_str()]];
 
     return event;
 }
@@ -5834,7 +5899,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         rect.origin.x = 19 - rect.size.width / 2;
         rect.origin.y = 19 - rect.size.height / 2;
 
-        [icon_ drawInRect:rect];
+        [icon_ drawInRect:Retina(rect)];
     }
 
     if (badge_ != nil) {
@@ -5847,7 +5912,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         rect.origin.x = 25 - rect.size.width / 2;
         rect.origin.y = 25 - rect.size.height / 2;
 
-        [badge_ drawInRect:rect];
+        [badge_ drawInRect:Retina(rect)];
     }
 
     if (highlighted && kCFCoreFoundationVersionNumber < 800)
@@ -5877,7 +5942,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         rect.origin.x = 25 - rect.size.width / 2;
         rect.origin.y = 25 - rect.size.height / 2;
 
-        [icon_ drawInRect:rect];
+        [icon_ drawInRect:Retina(rect)];
     }
 
     if (badge_ != nil) {
@@ -5890,7 +5955,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         rect.origin.x = 36 - rect.size.width / 2;
         rect.origin.y = 36 - rect.size.height / 2;
 
-        [badge_ drawInRect:rect];
+        [badge_ drawInRect:Retina(rect)];
     }
 
     if (highlighted && kCFCoreFoundationVersionNumber < 800)
@@ -6032,7 +6097,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     UISetColor(Folder_);
     if (count_ != nil)
-        [count_ drawAtPoint:CGPointMake(10 + (30 - size.width) / 2, 18) withFont:Font12Bold_];
+        [count_ drawAtPoint:CGPointMake(Retina(10 + (30 - size.width) / 2), 18) withFont:Font12Bold_];
 }
 
 @end
@@ -6259,6 +6324,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 #endif
 
+- (void) setPageColor:(UIColor *)color {
+    return [super setPageColor:nil];
+}
+
 - (id) initWithDatabase:(Database *)database forPackage:(NSString *)name withReferrer:(NSString *)referrer {
     if ((self = [super init]) != nil) {
         database_ = database;
@@ -6403,7 +6472,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     UIViewAnimationCurve curve;
     [self getKeyboardCurve:&curve duration:&duration forNotification:notification];
 
-    CGRect kbframe = CGRectMake(round(center.x - bounds.size.width / 2.0), round(center.y - bounds.size.height / 2.0), bounds.size.width, bounds.size.height);
+    CGRect kbframe = CGRectMake(Retina(center.x - bounds.size.width / 2), Retina(center.y - bounds.size.height / 2), bounds.size.width, bounds.size.height);
     UIViewController *base = self;
     while ([base parentOrPresentingViewController] != nil)
         base = [base parentOrPresentingViewController];
@@ -6812,7 +6881,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     [alert setCancelButtonIndex:0];
 
     [alert setMessage:
-        @"Copyright \u00a9 2008-2013\n"
+        @"Copyright \u00a9 2008-2014\n"
         "SaurikIT, LLC\n"
         "\n"
         "Jay Freeman (saurik)\n"
@@ -6978,15 +7047,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     updatedelegate_ = delegate;
 }
 
-- (UIView *) transitionView {
-    if (![self respondsToSelector:@selector(_transitionView)])
-        return MSHookIvar<id>(self, "_viewControllerTransitionView");
-    else if (kCFCoreFoundationVersionNumber < 800)
-        return [self _transitionView];
-    else
-        return [[[self _transitionView] superview] superview];
-}
-
 @end
 /* }}} */
 
@@ -8000,14 +8060,21 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
         Package *package([packages objectAtIndex:offset]);
 
         time_t upgraded([package upgraded]);
-        upgraded -= upgraded % (60 * 60 * 24);
+        if (upgraded < 1168364520)
+            upgraded = 0;
+        else
+            upgraded -= upgraded % (60 * 60 * 24);
 
         if (section == nil || upgraded != last) {
             last = upgraded;
 
             NSString *name;
-            name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) [NSDate dateWithTimeIntervalSince1970:upgraded]);
-            [name autorelease];
+            if (upgraded == 0)
+                continue; // XXX: name = UCLocalize("...");
+            else {
+                name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) [NSDate dateWithTimeIntervalSince1970:upgraded]);
+                [name autorelease];
+            }
 
             section = [[[Section alloc] initWithName:name row:offset localize:NO] autorelease];
             [sections addObject:section];
@@ -8043,14 +8110,14 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 - (void) queueStatusDidChange {
 #if !AlwaysReload
     if (Queuing_) {
-        [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc]
+        [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc]
             initWithTitle:UCLocalize("QUEUE")
             style:UIBarButtonItemStyleDone
             target:self
             action:@selector(queueButtonClicked)
         ] autorelease]];
     } else {
-        [[self navigationItem] setLeftBarButtonItem:nil];
+        [[self navigationItem] setRightBarButtonItem:nil];
     }
 #endif
 }
@@ -8165,7 +8232,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 
     CGRect frame([indicator_ frame]);
     frame.origin.x = bounds.size.width - frame.size.width;
-    frame.origin.y = (bounds.size.height - frame.size.height) / 2;
+    frame.origin.y = Retina((bounds.size.height - frame.size.height) / 2);
 
     if (kCFCoreFoundationVersionNumber < 800)
         frame.origin.x -= 8;
@@ -8192,7 +8259,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
         rect.origin.x = 26 - rect.size.width / 2;
         rect.origin.y = 26 - rect.size.height / 2;
 
-        [icon_ drawInRect:rect];
+        [icon_ drawInRect:Retina(rect)];
     }
 
     if (highlighted && kCFCoreFoundationVersionNumber < 800)
@@ -8200,11 +8267,11 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 
     if (!highlighted)
         UISetColor(Black_);
-    [origin_ drawAtPoint:CGPointMake(52, 8) forWidth:(width - 61) withFont:Font18Bold_ lineBreakMode:NSLineBreakByTruncatingTail];
+    [origin_ drawAtPoint:CGPointMake(52, 8) forWidth:(width - 49) withFont:Font18Bold_ lineBreakMode:NSLineBreakByTruncatingTail];
 
     if (!highlighted)
         UISetColor(Gray_);
-    [label_ drawAtPoint:CGPointMake(52, 29) forWidth:(width - 61) withFont:Font12_ lineBreakMode:NSLineBreakByTruncatingTail];
+    [label_ drawAtPoint:CGPointMake(52, 29) forWidth:(width - 49) withFont:Font12_ lineBreakMode:NSLineBreakByTruncatingTail];
 }
 
 - (void) setFetch:(NSNumber *)fetch {
@@ -8722,7 +8789,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 
     spinner_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease];
     CGRect spinrect = [spinner_ frame];
-    spinrect.origin.x = ([[self view] frame].size.width / 2) - (spinrect.size.width / 2);
+    spinrect.origin.x = Retina([[self view] frame].size.width / 2 - spinrect.size.width / 2);
     spinrect.origin.y = [[self view] frame].size.height - 80.0f;
     [spinner_ setFrame:spinrect];
     [spinner_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin];
@@ -8733,7 +8800,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     captrect.size.width = [[self view] frame].size.width;
     captrect.size.height = 40.0f;
     captrect.origin.x = 0;
-    captrect.origin.y = ([[self view] frame].size.height / 2) - (captrect.size.height * 2);
+    captrect.origin.y = Retina([[self view] frame].size.height / 2 - captrect.size.height * 2);
     caption_ = [[[UILabel alloc] initWithFrame:captrect] autorelease];
     [caption_ setText:UCLocalize("PREPARING_FILESYSTEM")];
     [caption_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin];
@@ -8748,7 +8815,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
     statusrect.size.width = [[self view] frame].size.width;
     statusrect.size.height = 30.0f;
     statusrect.origin.x = 0;
-    statusrect.origin.y = ([[self view] frame].size.height / 2) - statusrect.size.height;
+    statusrect.origin.y = Retina([[self view] frame].size.height / 2 - statusrect.size.height);
     status_ = [[[UILabel alloc] initWithFrame:statusrect] autorelease];
     [status_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin];
     [status_ setText:UCLocalize("EXIT_WHEN_COMPLETE")];
@@ -8821,13 +8888,11 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi
 @interface Cydia : UIApplication <
     ConfirmationControllerDelegate,
     DatabaseDelegate,
-    CydiaDelegate,
-    UINavigationControllerDelegate,
-    UITabBarControllerDelegate
+    CydiaDelegate
 > {
     _H<UIWindow> window_;
     _H<CydiaTabBarController> tabbar_;
-    _H<CydiaLoadingViewController> emulated_;
+    _H<CyteTabBarController> emulated_;
 
     _H<NSMutableArray> essential_;
     _H<NSMutableArray> broken_;
@@ -9792,7 +9857,17 @@ _trace();
     [window_ setUserInteractionEnabled:NO];
     [self setupViewControllers];
 
-    emulated_ = [[[CydiaLoadingViewController alloc] init] autorelease];
+    CydiaLoadingViewController *loading([[[CydiaLoadingViewController alloc] init] autorelease]);
+    UINavigationController *navigation([[[UINavigationController alloc] init] autorelease]);
+    [navigation setViewControllers:[NSArray arrayWithObject:loading]];
+
+    emulated_ = [[[CyteTabBarController alloc] init] autorelease];
+    [emulated_ setViewControllers:[NSArray arrayWithObject:navigation]];
+    [emulated_ setSelectedIndex:0];
+
+    if ([emulated_ respondsToSelector:@selector(concealTabBarSelection)])
+        [emulated_ concealTabBarSelection];
+
     if ([window_ respondsToSelector:@selector(setRootViewController:)])
         [window_ setRootViewController:emulated_];
     else
@@ -10155,7 +10230,7 @@ int main(int argc, char *argv[]) {
         NSString *path([bundle pathForResource:@"UITableViewLocalizedSectionIndex" ofType:@"plist"]);
         //path = @"/System/Library/Frameworks/UIKit.framework/.lproj/UITableViewLocalizedSectionIndex.plist";
         NSDictionary *dictionary([NSDictionary dictionaryWithContentsOfFile:path]);
-        _H<UILocalizedIndexedCollation> collation([[[UILocalizedIndexedCollation alloc] initWithDictionary:dictionary] autorelease]);
+        _H<UILocalizedIndexedCollation> collation([[[$UILocalizedIndexedCollation alloc] initWithDictionary:dictionary] autorelease]);
 
         CollationLocale_ = MSHookIvar<NSLocale *>(collation, "_locale");
 
@@ -10263,6 +10338,11 @@ int main(int argc, char *argv[]) {
     else
         Machine_ = machine;
 
+    int64_t usermem(0);
+    size = sizeof(usermem);
+    if (sysctlbyname("hw.usermem", &usermem, &size, NULL, 0) == -1)
+        usermem = 0;
+
     SerialNumber_ = (NSString *) CYIOGetValue("IOService:/", @"IOPlatformSerialNumber");
     ChipID_ = [CYHex((NSData *) CYIOGetValue("IODeviceTree:/chosen", @"unique-chip-id"), true) uppercaseString];
     BBSNum_ = CYHex((NSData *) CYIOGetValue("IOService:/AppleARMPE/baseband", @"snum"), false);
@@ -10419,7 +10499,7 @@ int main(int argc, char *argv[]) {
     // XXX: this timeout might be important :(
     //_config->Set("Acquire::http::Timeout", 15);
 
-    _config->Set("Acquire::http::MaxParallel", 3);
+    _config->Set("Acquire::http::MaxParallel", usermem >= 384 * 1024 * 1024 ? 16 : 3);
     /* }}} */
     /* Color Choices {{{ */
     space_ = CGColorSpaceCreateDeviceRGB();