xref: /aosp_15_r20/external/webrtc/examples/objc/AppRTCMobile/common/ARDUtilities.m (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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