123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- //
- // UIDevice+YYAdd.m
- // YYKit <https://github.com/ibireme/YYKit>
- //
- // Created by ibireme on 13/4/3.
- // Copyright (c) 2015 ibireme.
- //
- // This source code is licensed under the MIT-style license found in the
- // LICENSE file in the root directory of this source tree.
- //
- #import "UIDevice+YYAdd.h"
- #include <sys/socket.h>
- #include <sys/sysctl.h>
- #include <net/if.h>
- #include <net/if_dl.h>
- #include <mach/mach.h>
- #include <arpa/inet.h>
- #include <ifaddrs.h>
- #import "YYKitMacro.h"
- #import "NSString+YYAdd.h"
- YYSYNTH_DUMMY_CLASS(UIDevice_YYAdd)
- @implementation UIDevice (YYAdd)
- + (double)systemVersion {
- static double version;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- version = [UIDevice currentDevice].systemVersion.doubleValue;
- });
- return version;
- }
- - (BOOL)isPad {
- static dispatch_once_t one;
- static BOOL pad;
- dispatch_once(&one, ^{
- pad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
- });
- return pad;
- }
- - (BOOL)isSimulator {
- #if TARGET_OS_SIMULATOR
- return YES;
- #else
- return NO;
- #endif
- }
- - (BOOL)isJailbroken {
- if ([self isSimulator]) return NO; // Dont't check simulator
-
- // iOS9 URL Scheme query changed ...
- // NSURL *cydiaURL = [NSURL URLWithString:@"cydia://package"];
- // if ([[UIApplication sharedApplication] canOpenURL:cydiaURL]) return YES;
-
- NSArray *paths = @[@"/Applications/Cydia.app",
- @"/private/var/lib/apt/",
- @"/private/var/lib/cydia",
- @"/private/var/stash"];
- for (NSString *path in paths) {
- if ([[NSFileManager defaultManager] fileExistsAtPath:path]) return YES;
- }
-
- FILE *bash = fopen("/bin/bash", "r");
- if (bash != NULL) {
- fclose(bash);
- return YES;
- }
-
- NSString *path = [NSString stringWithFormat:@"/private/%@", [NSString stringWithUUID]];
- if ([@"test" writeToFile : path atomically : YES encoding : NSUTF8StringEncoding error : NULL]) {
- [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
- return YES;
- }
-
- return NO;
- }
- #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
- - (BOOL)canMakePhoneCalls {
- __block BOOL can;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- can = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]];
- });
- return can;
- }
- #endif
- - (NSString *)ipAddressWithIfaName:(NSString *)name {
- if (name.length == 0) return nil;
- NSString *address = nil;
- struct ifaddrs *addrs = NULL;
- if (getifaddrs(&addrs) == 0) {
- struct ifaddrs *addr = addrs;
- while (addr) {
- if ([[NSString stringWithUTF8String:addr->ifa_name] isEqualToString:name]) {
- sa_family_t family = addr->ifa_addr->sa_family;
- switch (family) {
- case AF_INET: { // IPv4
- char str[INET_ADDRSTRLEN] = {0};
- inet_ntop(family, &(((struct sockaddr_in *)addr->ifa_addr)->sin_addr), str, sizeof(str));
- if (strlen(str) > 0) {
- address = [NSString stringWithUTF8String:str];
- }
- } break;
-
- case AF_INET6: { // IPv6
- char str[INET6_ADDRSTRLEN] = {0};
- inet_ntop(family, &(((struct sockaddr_in6 *)addr->ifa_addr)->sin6_addr), str, sizeof(str));
- if (strlen(str) > 0) {
- address = [NSString stringWithUTF8String:str];
- }
- }
-
- default: break;
- }
- if (address) break;
- }
- addr = addr->ifa_next;
- }
- }
- freeifaddrs(addrs);
- return address;
- }
- - (NSString *)ipAddressWIFI {
- return [self ipAddressWithIfaName:@"en0"];
- }
- - (NSString *)ipAddressCell {
- return [self ipAddressWithIfaName:@"pdp_ip0"];
- }
- typedef struct {
- uint64_t en_in;
- uint64_t en_out;
- uint64_t pdp_ip_in;
- uint64_t pdp_ip_out;
- uint64_t awdl_in;
- uint64_t awdl_out;
- } yy_net_interface_counter;
- static uint64_t yy_net_counter_add(uint64_t counter, uint64_t bytes) {
- if (bytes < (counter % 0xFFFFFFFF)) {
- counter += 0xFFFFFFFF - (counter % 0xFFFFFFFF);
- counter += bytes;
- } else {
- counter = bytes;
- }
- return counter;
- }
- static uint64_t yy_net_counter_get_by_type(yy_net_interface_counter *counter, YYNetworkTrafficType type) {
- uint64_t bytes = 0;
- if (type & YYNetworkTrafficTypeWWANSent) bytes += counter->pdp_ip_out;
- if (type & YYNetworkTrafficTypeWWANReceived) bytes += counter->pdp_ip_in;
- if (type & YYNetworkTrafficTypeWIFISent) bytes += counter->en_out;
- if (type & YYNetworkTrafficTypeWIFIReceived) bytes += counter->en_in;
- if (type & YYNetworkTrafficTypeAWDLSent) bytes += counter->awdl_out;
- if (type & YYNetworkTrafficTypeAWDLReceived) bytes += counter->awdl_in;
- return bytes;
- }
- static yy_net_interface_counter yy_get_net_interface_counter() {
- static dispatch_semaphore_t lock;
- static NSMutableDictionary *sharedInCounters;
- static NSMutableDictionary *sharedOutCounters;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- sharedInCounters = [NSMutableDictionary new];
- sharedOutCounters = [NSMutableDictionary new];
- lock = dispatch_semaphore_create(1);
- });
-
- yy_net_interface_counter counter = {0};
- struct ifaddrs *addrs;
- const struct ifaddrs *cursor;
- if (getifaddrs(&addrs) == 0) {
- cursor = addrs;
- dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
- while (cursor) {
- if (cursor->ifa_addr->sa_family == AF_LINK) {
- const struct if_data *data = cursor->ifa_data;
- NSString *name = cursor->ifa_name ? [NSString stringWithUTF8String:cursor->ifa_name] : nil;
- if (name) {
- uint64_t counter_in = ((NSNumber *)sharedInCounters[name]).unsignedLongLongValue;
- counter_in = yy_net_counter_add(counter_in, data->ifi_ibytes);
- sharedInCounters[name] = @(counter_in);
-
- uint64_t counter_out = ((NSNumber *)sharedOutCounters[name]).unsignedLongLongValue;
- counter_out = yy_net_counter_add(counter_out, data->ifi_obytes);
- sharedOutCounters[name] = @(counter_out);
-
- if ([name hasPrefix:@"en"]) {
- counter.en_in += counter_in;
- counter.en_out += counter_out;
- } else if ([name hasPrefix:@"awdl"]) {
- counter.awdl_in += counter_in;
- counter.awdl_out += counter_out;
- } else if ([name hasPrefix:@"pdp_ip"]) {
- counter.pdp_ip_in += counter_in;
- counter.pdp_ip_out += counter_out;
- }
- }
- }
- cursor = cursor->ifa_next;
- }
- dispatch_semaphore_signal(lock);
- freeifaddrs(addrs);
- }
-
- return counter;
- }
- - (uint64_t)getNetworkTrafficBytes:(YYNetworkTrafficType)types {
- yy_net_interface_counter counter = yy_get_net_interface_counter();
- return yy_net_counter_get_by_type(&counter, types);
- }
- - (NSString *)machineModel {
- static dispatch_once_t one;
- static NSString *model;
- dispatch_once(&one, ^{
- size_t size;
- sysctlbyname("hw.machine", NULL, &size, NULL, 0);
- char *machine = malloc(size);
- sysctlbyname("hw.machine", machine, &size, NULL, 0);
- model = [NSString stringWithUTF8String:machine];
- free(machine);
- });
- return model;
- }
- - (NSString *)machineModelName {
- static dispatch_once_t one;
- static NSString *name;
- dispatch_once(&one, ^{
- NSString *model = [self machineModel];
- if (!model) return;
- NSDictionary *dic = @{
- @"Watch1,1" : @"Apple Watch 38mm",
- @"Watch1,2" : @"Apple Watch 42mm",
- @"Watch2,3" : @"Apple Watch Series 2 38mm",
- @"Watch2,4" : @"Apple Watch Series 2 42mm",
- @"Watch2,6" : @"Apple Watch Series 1 38mm",
- @"Watch1,7" : @"Apple Watch Series 1 42mm",
-
- @"iPod1,1" : @"iPod touch 1",
- @"iPod2,1" : @"iPod touch 2",
- @"iPod3,1" : @"iPod touch 3",
- @"iPod4,1" : @"iPod touch 4",
- @"iPod5,1" : @"iPod touch 5",
- @"iPod7,1" : @"iPod touch 6",
-
- @"iPhone1,1" : @"iPhone 1G",
- @"iPhone1,2" : @"iPhone 3G",
- @"iPhone2,1" : @"iPhone 3GS",
- @"iPhone3,1" : @"iPhone 4 (GSM)",
- @"iPhone3,2" : @"iPhone 4",
- @"iPhone3,3" : @"iPhone 4 (CDMA)",
- @"iPhone4,1" : @"iPhone 4S",
- @"iPhone5,1" : @"iPhone 5",
- @"iPhone5,2" : @"iPhone 5",
- @"iPhone5,3" : @"iPhone 5c",
- @"iPhone5,4" : @"iPhone 5c",
- @"iPhone6,1" : @"iPhone 5s",
- @"iPhone6,2" : @"iPhone 5s",
- @"iPhone7,1" : @"iPhone 6 Plus",
- @"iPhone7,2" : @"iPhone 6",
- @"iPhone8,1" : @"iPhone 6s",
- @"iPhone8,2" : @"iPhone 6s Plus",
- @"iPhone8,4" : @"iPhone SE",
- @"iPhone9,1" : @"iPhone 7",
- @"iPhone9,2" : @"iPhone 7 Plus",
- @"iPhone9,3" : @"iPhone 7",
- @"iPhone9,4" : @"iPhone 7 Plus",
-
- @"iPad1,1" : @"iPad 1",
- @"iPad2,1" : @"iPad 2 (WiFi)",
- @"iPad2,2" : @"iPad 2 (GSM)",
- @"iPad2,3" : @"iPad 2 (CDMA)",
- @"iPad2,4" : @"iPad 2",
- @"iPad2,5" : @"iPad mini 1",
- @"iPad2,6" : @"iPad mini 1",
- @"iPad2,7" : @"iPad mini 1",
- @"iPad3,1" : @"iPad 3 (WiFi)",
- @"iPad3,2" : @"iPad 3 (4G)",
- @"iPad3,3" : @"iPad 3 (4G)",
- @"iPad3,4" : @"iPad 4",
- @"iPad3,5" : @"iPad 4",
- @"iPad3,6" : @"iPad 4",
- @"iPad4,1" : @"iPad Air",
- @"iPad4,2" : @"iPad Air",
- @"iPad4,3" : @"iPad Air",
- @"iPad4,4" : @"iPad mini 2",
- @"iPad4,5" : @"iPad mini 2",
- @"iPad4,6" : @"iPad mini 2",
- @"iPad4,7" : @"iPad mini 3",
- @"iPad4,8" : @"iPad mini 3",
- @"iPad4,9" : @"iPad mini 3",
- @"iPad5,1" : @"iPad mini 4",
- @"iPad5,2" : @"iPad mini 4",
- @"iPad5,3" : @"iPad Air 2",
- @"iPad5,4" : @"iPad Air 2",
- @"iPad6,3" : @"iPad Pro (9.7 inch)",
- @"iPad6,4" : @"iPad Pro (9.7 inch)",
- @"iPad6,7" : @"iPad Pro (12.9 inch)",
- @"iPad6,8" : @"iPad Pro (12.9 inch)",
-
- @"AppleTV2,1" : @"Apple TV 2",
- @"AppleTV3,1" : @"Apple TV 3",
- @"AppleTV3,2" : @"Apple TV 3",
- @"AppleTV5,3" : @"Apple TV 4",
-
- @"i386" : @"Simulator x86",
- @"x86_64" : @"Simulator x64",
- };
- name = dic[model];
- if (!name) name = model;
- });
- return name;
- }
- - (NSDate *)systemUptime {
- NSTimeInterval time = [[NSProcessInfo processInfo] systemUptime];
- return [[NSDate alloc] initWithTimeIntervalSinceNow:(0 - time)];
- }
- - (int64_t)diskSpace {
- NSError *error = nil;
- NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
- if (error) return -1;
- int64_t space = [[attrs objectForKey:NSFileSystemSize] longLongValue];
- if (space < 0) space = -1;
- return space;
- }
- - (int64_t)diskSpaceFree {
- NSError *error = nil;
- NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
- if (error) return -1;
- int64_t space = [[attrs objectForKey:NSFileSystemFreeSize] longLongValue];
- if (space < 0) space = -1;
- return space;
- }
- - (int64_t)diskSpaceUsed {
- int64_t total = self.diskSpace;
- int64_t free = self.diskSpaceFree;
- if (total < 0 || free < 0) return -1;
- int64_t used = total - free;
- if (used < 0) used = -1;
- return used;
- }
- - (int64_t)memoryTotal {
- int64_t mem = [[NSProcessInfo processInfo] physicalMemory];
- if (mem < -1) mem = -1;
- return mem;
- }
- - (int64_t)memoryUsed {
- mach_port_t host_port = mach_host_self();
- mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
- vm_size_t page_size;
- vm_statistics_data_t vm_stat;
- kern_return_t kern;
-
- kern = host_page_size(host_port, &page_size);
- if (kern != KERN_SUCCESS) return -1;
- kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
- if (kern != KERN_SUCCESS) return -1;
- return page_size * (vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count);
- }
- - (int64_t)memoryFree {
- mach_port_t host_port = mach_host_self();
- mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
- vm_size_t page_size;
- vm_statistics_data_t vm_stat;
- kern_return_t kern;
-
- kern = host_page_size(host_port, &page_size);
- if (kern != KERN_SUCCESS) return -1;
- kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
- if (kern != KERN_SUCCESS) return -1;
- return vm_stat.free_count * page_size;
- }
- - (int64_t)memoryActive {
- mach_port_t host_port = mach_host_self();
- mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
- vm_size_t page_size;
- vm_statistics_data_t vm_stat;
- kern_return_t kern;
-
- kern = host_page_size(host_port, &page_size);
- if (kern != KERN_SUCCESS) return -1;
- kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
- if (kern != KERN_SUCCESS) return -1;
- return vm_stat.active_count * page_size;
- }
- - (int64_t)memoryInactive {
- mach_port_t host_port = mach_host_self();
- mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
- vm_size_t page_size;
- vm_statistics_data_t vm_stat;
- kern_return_t kern;
-
- kern = host_page_size(host_port, &page_size);
- if (kern != KERN_SUCCESS) return -1;
- kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
- if (kern != KERN_SUCCESS) return -1;
- return vm_stat.inactive_count * page_size;
- }
- - (int64_t)memoryWired {
- mach_port_t host_port = mach_host_self();
- mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
- vm_size_t page_size;
- vm_statistics_data_t vm_stat;
- kern_return_t kern;
-
- kern = host_page_size(host_port, &page_size);
- if (kern != KERN_SUCCESS) return -1;
- kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
- if (kern != KERN_SUCCESS) return -1;
- return vm_stat.wire_count * page_size;
- }
- - (int64_t)memoryPurgable {
- mach_port_t host_port = mach_host_self();
- mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
- vm_size_t page_size;
- vm_statistics_data_t vm_stat;
- kern_return_t kern;
-
- kern = host_page_size(host_port, &page_size);
- if (kern != KERN_SUCCESS) return -1;
- kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
- if (kern != KERN_SUCCESS) return -1;
- return vm_stat.purgeable_count * page_size;
- }
- - (NSUInteger)cpuCount {
- return [NSProcessInfo processInfo].activeProcessorCount;
- }
- - (float)cpuUsage {
- float cpu = 0;
- NSArray *cpus = [self cpuUsagePerProcessor];
- if (cpus.count == 0) return -1;
- for (NSNumber *n in cpus) {
- cpu += n.floatValue;
- }
- return cpu;
- }
- - (NSArray *)cpuUsagePerProcessor {
- processor_info_array_t _cpuInfo, _prevCPUInfo = nil;
- mach_msg_type_number_t _numCPUInfo, _numPrevCPUInfo = 0;
- unsigned _numCPUs;
- NSLock *_cpuUsageLock;
-
- int _mib[2U] = { CTL_HW, HW_NCPU };
- size_t _sizeOfNumCPUs = sizeof(_numCPUs);
- int _status = sysctl(_mib, 2U, &_numCPUs, &_sizeOfNumCPUs, NULL, 0U);
- if (_status)
- _numCPUs = 1;
-
- _cpuUsageLock = [[NSLock alloc] init];
-
- natural_t _numCPUsU = 0U;
- kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &_numCPUsU, &_cpuInfo, &_numCPUInfo);
- if (err == KERN_SUCCESS) {
- [_cpuUsageLock lock];
-
- NSMutableArray *cpus = [NSMutableArray new];
- for (unsigned i = 0U; i < _numCPUs; ++i) {
- Float32 _inUse, _total;
- if (_prevCPUInfo) {
- _inUse = (
- (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER])
- + (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM])
- + (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE])
- );
- _total = _inUse + (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE]);
- } else {
- _inUse = _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER] + _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM] + _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE];
- _total = _inUse + _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE];
- }
- [cpus addObject:@(_inUse / _total)];
- }
-
- [_cpuUsageLock unlock];
- if (_prevCPUInfo) {
- size_t prevCpuInfoSize = sizeof(integer_t) * _numPrevCPUInfo;
- vm_deallocate(mach_task_self(), (vm_address_t)_prevCPUInfo, prevCpuInfoSize);
- }
- return cpus;
- } else {
- return nil;
- }
- }
- @end
|