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