[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / components / power_metrics / m1_sensors_mac.mm
1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/power_metrics/m1_sensors_mac.h"
6
7 #include <CoreFoundation/CoreFoundation.h>
8 #import <Foundation/Foundation.h>
9 #import <IOKit/hid/IOHIDDeviceKeys.h>
10 #import <IOKit/hidsystem/IOHIDServiceClient.h>
11
12 #include <utility>
13
14 #include "base/apple/bridging.h"
15 #include "base/apple/foundation_util.h"
16 #include "base/memory/ptr_util.h"
17 #include "components/power_metrics/m1_sensors_internal_types_mac.h"
18
19 extern "C" {
20
21 extern IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef);
22 extern int IOHIDEventSystemClientSetMatching(IOHIDEventSystemClientRef client,
23                                              CFDictionaryRef match);
24 extern CFTypeRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef,
25                                              int64_t,
26                                              int32_t,
27                                              int64_t);
28 extern double IOHIDEventGetFloatValue(CFTypeRef, int32_t);
29 }
30
31 namespace power_metrics {
32
33 namespace {
34
35 absl::optional<double> GetEventFloatValue(IOHIDServiceClientRef service,
36                                           int64_t event_type) {
37   base::apple::ScopedCFTypeRef<CFTypeRef> event(
38       IOHIDServiceClientCopyEvent(service, event_type, 0, 0));
39   if (!event)
40     return absl::nullopt;
41   return IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(event_type));
42 }
43
44 }  // namespace
45
46 M1SensorsReader::TemperaturesCelsius::TemperaturesCelsius() = default;
47 M1SensorsReader::TemperaturesCelsius::TemperaturesCelsius(
48     const TemperaturesCelsius&) noexcept = default;
49 M1SensorsReader::TemperaturesCelsius::~TemperaturesCelsius() = default;
50
51 M1SensorsReader::~M1SensorsReader() = default;
52
53 // static
54 std::unique_ptr<M1SensorsReader> M1SensorsReader::Create() {
55   base::apple::ScopedCFTypeRef<IOHIDEventSystemClientRef> system(
56       IOHIDEventSystemClientCreate(kCFAllocatorDefault));
57
58   if (system == nil)
59     return nullptr;
60
61   NSDictionary* filter = @{
62     @kIOHIDPrimaryUsagePageKey : @(kHIDPage_AppleVendor),
63     @kIOHIDPrimaryUsageKey : @(kHIDUsage_AppleVendor_TemperatureSensor),
64   };
65   IOHIDEventSystemClientSetMatching(system, base::apple::NSToCFPtrCast(filter));
66
67   return base::WrapUnique(new M1SensorsReader(std::move(system)));
68 }
69
70 M1SensorsReader::TemperaturesCelsius M1SensorsReader::ReadTemperatures() {
71   base::apple::ScopedCFTypeRef<CFArrayRef> services(
72       IOHIDEventSystemClientCopyServices(system_.get()));
73
74   // There are multiple temperature sensors on P-Cores and E-Cores. Count and
75   // sum values to compute average later.
76   int num_p_core_temp = 0;
77   int num_e_core_temp = 0;
78   double sum_p_core_temp = 0;
79   double sum_e_core_temp = 0;
80
81   for (CFIndex i = 0; i < CFArrayGetCount(services); ++i) {
82     IOHIDServiceClientRef service =
83         (IOHIDServiceClientRef)CFArrayGetValueAtIndex(services, i);
84
85     base::apple::ScopedCFTypeRef<CFStringRef> product(
86         base::apple::CFCast<CFStringRef>(
87             IOHIDServiceClientCopyProperty(service, CFSTR(kIOHIDProductKey))));
88     if (product == nil) {
89       continue;
90     }
91
92     if (CFStringHasPrefix(product, CFSTR("pACC MTR Temp Sensor"))) {
93       absl::optional<double> temp =
94           GetEventFloatValue(service, kIOHIDEventTypeTemperature);
95       if (temp.has_value()) {
96         num_p_core_temp += 1;
97         sum_p_core_temp += temp.value();
98       }
99     }
100
101     if (CFStringHasPrefix(product, CFSTR("eACC MTR Temp Sensor"))) {
102       absl::optional<double> temp =
103           GetEventFloatValue(service, kIOHIDEventTypeTemperature);
104       if (temp.has_value()) {
105         num_e_core_temp += 1;
106         sum_e_core_temp += temp.value();
107       }
108     }
109   }
110
111   TemperaturesCelsius temperatures;
112   if (num_p_core_temp > 0)
113     temperatures.p_cores = sum_p_core_temp / num_p_core_temp;
114   if (num_e_core_temp > 0)
115     temperatures.e_cores = sum_e_core_temp / num_e_core_temp;
116
117   return temperatures;
118 }
119
120 M1SensorsReader::M1SensorsReader(
121     base::apple::ScopedCFTypeRef<IOHIDEventSystemClientRef> system)
122     : system_(std::move(system)) {}
123
124 }  // namespace power_metrics