1/* 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#import "ARDUtilities.h" 12 13#import <mach/mach.h> 14 15#import "RTCLogging.h" 16 17@implementation NSDictionary (ARDUtilites) 18 19+ (NSDictionary *)dictionaryWithJSONString:(NSString *)jsonString { 20 NSParameterAssert(jsonString.length > 0); 21 NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 22 NSError *error = nil; 23 NSDictionary *dict = 24 [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 25 if (error) { 26 RTCLogError(@"Error parsing JSON: %@", error.localizedDescription); 27 } 28 return dict; 29} 30 31+ (NSDictionary *)dictionaryWithJSONData:(NSData *)jsonData { 32 NSError *error = nil; 33 NSDictionary *dict = 34 [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; 35 if (error) { 36 RTCLogError(@"Error parsing JSON: %@", error.localizedDescription); 37 } 38 return dict; 39} 40 41@end 42 43@implementation NSURLConnection (ARDUtilities) 44 45+ (void)sendAsyncRequest:(NSURLRequest *)request 46 completionHandler:(void (^)(NSURLResponse *response, 47 NSData *data, 48 NSError *error))completionHandler { 49 // Kick off an async request which will call back on main thread. 50 [NSURLConnection sendAsynchronousRequest:request 51 queue:[NSOperationQueue mainQueue] 52 completionHandler:^(NSURLResponse *response, 53 NSData *data, 54 NSError *error) { 55 if (completionHandler) { 56 completionHandler(response, data, error); 57 } 58 }]; 59} 60 61// Posts data to the specified URL. 62+ (void)sendAsyncPostToURL:(NSURL *)url 63 withData:(NSData *)data 64 completionHandler:(void (^)(BOOL succeeded, 65 NSData *data))completionHandler { 66 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 67 request.HTTPMethod = @"POST"; 68 request.HTTPBody = data; 69 [[self class] sendAsyncRequest:request 70 completionHandler:^(NSURLResponse *response, 71 NSData *data, 72 NSError *error) { 73 if (error) { 74 RTCLogError(@"Error posting data: %@", error.localizedDescription); 75 if (completionHandler) { 76 completionHandler(NO, data); 77 } 78 return; 79 } 80 NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 81 if (httpResponse.statusCode != 200) { 82 NSString *serverResponse = data.length > 0 ? 83 [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : 84 nil; 85 RTCLogError(@"Received bad response: %@", serverResponse); 86 if (completionHandler) { 87 completionHandler(NO, data); 88 } 89 return; 90 } 91 if (completionHandler) { 92 completionHandler(YES, data); 93 } 94 }]; 95} 96 97@end 98 99NSInteger ARDGetCpuUsagePercentage() { 100 // Create an array of thread ports for the current task. 101 const task_t task = mach_task_self(); 102 thread_act_array_t thread_array; 103 mach_msg_type_number_t thread_count; 104 if (task_threads(task, &thread_array, &thread_count) != KERN_SUCCESS) { 105 return -1; 106 } 107 108 // Sum cpu usage from all threads. 109 float cpu_usage_percentage = 0; 110 thread_basic_info_data_t thread_info_data = {}; 111 mach_msg_type_number_t thread_info_count; 112 for (size_t i = 0; i < thread_count; ++i) { 113 thread_info_count = THREAD_BASIC_INFO_COUNT; 114 kern_return_t ret = thread_info(thread_array[i], 115 THREAD_BASIC_INFO, 116 (thread_info_t)&thread_info_data, 117 &thread_info_count); 118 if (ret == KERN_SUCCESS) { 119 cpu_usage_percentage += 120 100.f * (float)thread_info_data.cpu_usage / TH_USAGE_SCALE; 121 } 122 } 123 124 // Dealloc the created array. 125 vm_deallocate(task, (vm_address_t)thread_array, 126 sizeof(thread_act_t) * thread_count); 127 return lroundf(cpu_usage_percentage); 128} 129