]> git.saurik.com Git - cydia.git/blob - CyteKit/CyteObject.mm
Mostly make Cydia compile using the iOS Simulator.
[cydia.git] / CyteKit / CyteObject.mm
1 /* Cydia - iPhone UIKit Front-End for Debian APT
2 * Copyright (C) 2008-2015 Jay Freeman (saurik)
3 */
4
5 /* GNU General Public License, Version 3 {{{ */
6 /*
7 * Cydia is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation, either version 3 of the License,
10 * or (at your option) any later version.
11 *
12 * Cydia is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Cydia. If not, see <http://www.gnu.org/licenses/>.
19 **/
20 /* }}} */
21
22 #include "CyteKit/UCPlatform.h"
23
24 #include <sys/mount.h>
25 #include <sys/sysctl.h>
26
27 #include <IOKit/IOKitLib.h>
28 #include <objc/runtime.h>
29
30 #include "CyteKit/CyteObject.h"
31 #include "CyteKit/WebViewController.h"
32 #include "CyteKit/countByEnumeratingWithState.h"
33 #include "CyteKit/extern.h"
34
35 #include "iPhonePrivate.h"
36 #include <Menes/ObjectHandle.h>
37
38 @implementation NSDictionary (Cydia)
39 - (id) invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)arguments {
40 if (false);
41 else if ([name isEqualToString:@"get"])
42 return [self objectForKey:[arguments objectAtIndex:0]];
43 else if ([name isEqualToString:@"keys"])
44 return [self allKeys];
45 return nil;
46 } @end
47
48 static NSString *CYHex(NSData *data, bool reverse = false) {
49 if (data == nil)
50 return nil;
51
52 size_t length([data length]);
53 uint8_t bytes[length];
54 [data getBytes:bytes];
55
56 char string[length * 2 + 1];
57 for (size_t i(0); i != length; ++i)
58 sprintf(string + i * 2, "%.2x", bytes[reverse ? length - i - 1 : i]);
59
60 return [NSString stringWithUTF8String:string];
61 }
62
63 static NSObject *CYIOGetValue(const char *path, NSString *property) {
64 io_registry_entry_t entry(IORegistryEntryFromPath(kIOMasterPortDefault, path));
65 if (entry == MACH_PORT_NULL)
66 return nil;
67
68 CFTypeRef value(IORegistryEntryCreateCFProperty(entry, (CFStringRef) property, kCFAllocatorDefault, 0));
69 IOObjectRelease(entry);
70
71 if (value == NULL)
72 return nil;
73 return [(id) value autorelease];
74 }
75
76 @implementation CyteObject {
77 _H<CyteWebViewController> indirect_;
78 }
79
80 + (BOOL) isKeyExcludedFromWebScript:(const char *)name {
81 return false;
82 }
83
84 - (id) initWithDelegate:(CyteWebViewController *)indirect {
85 if ((self = [super init]) != nil) {
86 indirect_ = indirect;
87 } return self;
88 }
89
90
91 - (NSArray *) attributeKeys {
92 return [NSArray arrayWithObjects:
93 @"bbsnum",
94 @"bittage",
95 @"build",
96 @"coreFoundationVersionNumber",
97 @"ecid",
98 @"firmware",
99 @"hostname",
100 @"idiom",
101 @"model",
102 @"serial",
103 nil];
104 }
105
106 - (unsigned) bittage {
107 #if 0
108 #elif defined(__x86_64__)
109 return 64;
110 #elif defined(__arm64__)
111 return 64;
112 #elif defined(__arm__)
113 return 32;
114 #else
115 return 0;
116 #endif
117 }
118
119 - (NSString *) bbsnum {
120 return (id) CYHex((NSData *) CYIOGetValue("IOService:/AppleARMPE/baseband", @"snum"), false) ?: [NSNull null];
121 }
122
123 - (NSString *) build {
124 return [NSString stringWithUTF8String:System_];
125 }
126
127 - (NSString *) coreFoundationVersionNumber {
128 return [NSString stringWithFormat:@"%.2f", kCFCoreFoundationVersionNumber];
129 }
130
131 - (NSString *) ecid {
132 return (id) [CYHex((NSData *) CYIOGetValue("IODeviceTree:/chosen", @"unique-chip-id"), true) uppercaseString] ?: [NSNull null];
133 }
134
135 - (NSString *) firmware {
136 return [[UIDevice currentDevice] systemVersion];
137 }
138
139 - (NSString *) hostname {
140 return [[UIDevice currentDevice] name];
141 }
142
143 - (NSString *) idiom {
144 return IsWildcat_ ? @"ipad" : @"iphone";
145 }
146
147 - (NSString *) model {
148 return [NSString stringWithUTF8String:Machine_];
149 }
150
151 - (NSString *) serial {
152 return (NSString *) CYIOGetValue("IOService:/", @"IOPlatformSerialNumber");
153 }
154
155
156 + (NSString *) webScriptNameForSelector:(SEL)selector {
157 if (false);
158 else if (selector == @selector(addInternalRedirect::))
159 return @"addInternalRedirect";
160 else if (selector == @selector(close))
161 return @"close";
162 else if (selector == @selector(stringWithFormat:arguments:))
163 return @"format";
164 else if (selector == @selector(getIORegistryEntry::))
165 return @"getIORegistryEntry";
166 else if (selector == @selector(getKernelNumber:))
167 return @"getKernelNumber";
168 else if (selector == @selector(getKernelString:))
169 return @"getKernelString";
170 else if (selector == @selector(getLocaleIdentifier))
171 return @"getLocaleIdentifier";
172 else if (selector == @selector(getPreferredLanguages))
173 return @"getPreferredLanguages";
174 else if (selector == @selector(isReachable:))
175 return @"isReachable";
176 else if (selector == @selector(localizedStringForKey:value:table:))
177 return @"localize";
178 else if (selector == @selector(popViewController:))
179 return @"popViewController";
180 else if (selector == @selector(registerFrame:))
181 return @"registerFrame";
182 else if (selector == @selector(removeButton))
183 return @"removeButton";
184 else if (selector == @selector(scrollToBottom:))
185 return @"scrollToBottom";
186 else if (selector == @selector(setAllowsNavigationAction:))
187 return @"setAllowsNavigationAction";
188 else if (selector == @selector(setBadgeValue:))
189 return @"setBadgeValue";
190 else if (selector == @selector(setButtonImage:withStyle:toFunction:))
191 return @"setButtonImage";
192 else if (selector == @selector(setButtonTitle:withStyle:toFunction:))
193 return @"setButtonTitle";
194 else if (selector == @selector(setHidesBackButton:))
195 return @"setHidesBackButton";
196 else if (selector == @selector(setHidesNavigationBar:))
197 return @"setHidesNavigationBar";
198 else if (selector == @selector(setNavigationBarStyle:))
199 return @"setNavigationBarStyle";
200 else if (selector == @selector(setNavigationBarTintRed:green:blue:alpha:))
201 return @"setNavigationBarTintColor";
202 else if (selector == @selector(setPasteboardString:))
203 return @"setPasteboardString";
204 else if (selector == @selector(setPasteboardURL:))
205 return @"setPasteboardURL";
206 else if (selector == @selector(setScrollAlwaysBounceVertical:))
207 return @"setScrollAlwaysBounceVertical";
208 else if (selector == @selector(setScrollIndicatorStyle:))
209 return @"setScrollIndicatorStyle";
210 else if (selector == @selector(setViewportWidth:))
211 return @"setViewportWidth";
212 else if (selector == @selector(statfs:))
213 return @"statfs";
214 else if (selector == @selector(supports:))
215 return @"supports";
216 else if (selector == @selector(unload))
217 return @"unload";
218 else
219 return nil;
220 }
221
222 + (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
223 return [self webScriptNameForSelector:selector] == nil;
224 }
225
226 - (void) addInternalRedirect:(NSString *)from :(NSString *)to {
227 [CyteWebViewController performSelectorOnMainThread:@selector(addDiversion:) withObject:[[[Diversion alloc] initWithFrom:from to:to] autorelease] waitUntilDone:NO];
228 }
229
230 - (void) close {
231 [indirect_ performSelectorOnMainThread:@selector(close) withObject:nil waitUntilDone:NO];
232 }
233
234 - (NSString *) getKernelString:(NSString *)name {
235 const char *string([name UTF8String]);
236
237 size_t size;
238 if (sysctlbyname(string, NULL, &size, NULL, 0) == -1)
239 return (id) [NSNull null];
240
241 char value[size + 1];
242 if (sysctlbyname(string, value, &size, NULL, 0) == -1)
243 return (id) [NSNull null];
244
245 // XXX: just in case you request something ludicrous
246 value[size] = '\0';
247
248 return [NSString stringWithCString:value];
249 }
250
251 - (NSObject *) getIORegistryEntry:(NSString *)path :(NSString *)entry {
252 NSObject *value(CYIOGetValue([path UTF8String], entry));
253
254 if (value != nil)
255 if ([value isKindOfClass:[NSData class]])
256 value = CYHex((NSData *) value);
257
258 return value;
259 }
260
261 - (NSString *) getLocaleIdentifier {
262 _H<const __CFLocale> locale(CFLocaleCopyCurrent(), true);
263 return locale == NULL ? (NSString *) [NSNull null] : (NSString *) CFLocaleGetIdentifier(locale);
264 }
265
266 - (NSArray *) getPreferredLanguages {
267 return [NSLocale preferredLanguages];
268 }
269
270 - (NSNumber *) isReachable:(NSString *)name {
271 return [NSNumber numberWithBool:CyteIsReachable([name UTF8String])];
272 }
273
274 - (NSString *) localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)table {
275 if (reinterpret_cast<id>(value) == [WebUndefined undefined])
276 value = nil;
277 if (reinterpret_cast<id>(table) == [WebUndefined undefined])
278 table = nil;
279 return [[NSBundle mainBundle] localizedStringForKey:key value:value table:table];
280 }
281
282 - (void) popViewController:(NSNumber *)value {
283 if (value == (id) [WebUndefined undefined])
284 value = [NSNumber numberWithBool:YES];
285 [indirect_ performSelectorOnMainThread:@selector(popViewControllerWithNumber:) withObject:value waitUntilDone:NO];
286 }
287
288 - (void) registerFrame:(DOMHTMLIFrameElement *)iframe {
289 WebFrame *frame([iframe contentFrame]);
290 [indirect_ registerFrame:frame];
291 }
292
293 - (void) removeButton {
294 [indirect_ removeButton];
295 }
296
297 - (void) scrollToBottom:(NSNumber *)animated {
298 [indirect_ performSelectorOnMainThread:@selector(scrollToBottomAnimated:) withObject:animated waitUntilDone:NO];
299 }
300
301 - (void) setAllowsNavigationAction:(NSString *)value {
302 [indirect_ performSelectorOnMainThread:@selector(setAllowsNavigationActionByNumber:) withObject:value waitUntilDone:NO];
303 }
304
305 - (void) setBadgeValue:(id)value {
306 [indirect_ performSelectorOnMainThread:@selector(setBadgeValue:) withObject:value waitUntilDone:NO];
307 }
308
309 - (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function {
310 [indirect_ setButtonImage:button withStyle:style toFunction:function];
311 }
312
313 - (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function {
314 [indirect_ setButtonTitle:button withStyle:style toFunction:function];
315 }
316
317 - (void) setHidesBackButton:(NSString *)value {
318 [indirect_ performSelectorOnMainThread:@selector(setHidesBackButtonByNumber:) withObject:value waitUntilDone:NO];
319 }
320
321 - (void) setHidesNavigationBar:(NSString *)value {
322 [indirect_ performSelectorOnMainThread:@selector(setHidesNavigationBarByNumber:) withObject:value waitUntilDone:NO];
323 }
324
325 - (void) setNavigationBarStyle:(NSString *)value {
326 [indirect_ performSelectorOnMainThread:@selector(setNavigationBarStyle:) withObject:value waitUntilDone:NO];
327 }
328
329 - (void) setNavigationBarTintRed:(NSNumber *)red green:(NSNumber *)green blue:(NSNumber *)blue alpha:(NSNumber *)alpha {
330 float opacity(alpha == (id) [WebUndefined undefined] ? 1 : [alpha floatValue]);
331 UIColor *color([UIColor colorWithRed:[red floatValue] green:[green floatValue] blue:[blue floatValue] alpha:opacity]);
332 [indirect_ performSelectorOnMainThread:@selector(setNavigationBarTintColor:) withObject:color waitUntilDone:NO];
333 }
334
335 - (void) setPasteboardString:(NSString *)value {
336 [[objc_getClass("UIPasteboard") generalPasteboard] setString:value];
337 }
338
339 - (void) setPasteboardURL:(NSString *)value {
340 [[objc_getClass("UIPasteboard") generalPasteboard] setURL:[NSURL URLWithString:value]];
341 }
342
343 - (void) setScrollAlwaysBounceVertical:(NSNumber *)value {
344 [indirect_ performSelectorOnMainThread:@selector(setScrollAlwaysBounceVerticalNumber:) withObject:value waitUntilDone:NO];
345 }
346
347 - (void) setScrollIndicatorStyle:(NSString *)style {
348 [indirect_ performSelectorOnMainThread:@selector(setScrollIndicatorStyleWithName:) withObject:style waitUntilDone:NO];
349 }
350
351 - (void) setViewportWidth:(float)width {
352 [indirect_ setViewportWidthOnMainThread:width];
353 }
354
355 - (NSArray *) statfs:(NSString *)path {
356 struct statfs stat;
357
358 if (path == nil || statfs([path UTF8String], &stat) == -1)
359 return nil;
360
361 return [NSArray arrayWithObjects:
362 [NSNumber numberWithUnsignedLong:stat.f_bsize],
363 [NSNumber numberWithUnsignedLong:stat.f_blocks],
364 [NSNumber numberWithUnsignedLong:stat.f_bfree],
365 nil];
366 }
367
368 - (NSString *) stringWithFormat:(NSString *)format arguments:(WebScriptObject *)arguments {
369 //NSLog(@"SWF:\"%@\" A:%@", format, [arguments description]);
370 unsigned count([arguments count]);
371 id values[count];
372 for (unsigned i(0); i != count; ++i)
373 values[i] = [arguments objectAtIndex:i];
374 return [[[NSString alloc] initWithFormat:format arguments:reinterpret_cast<va_list>(values)] autorelease];
375 }
376
377 - (BOOL) supports:(NSString *)feature {
378 return [feature isEqualToString:@"window.open"];
379 }
380
381 - (void) unload {
382 [[indirect_ rootViewController] performSelectorOnMainThread:@selector(unloadData) withObject:nil waitUntilDone:NO];
383 }
384
385 @end