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