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 "base/power_monitor/iopm_power_source_sampling_event_source.h"
6
7 #include <IOKit/IOMessage.h>
8 #include <dispatch/queue.h>
9
10 #include "base/check.h"
11 #include "base/logging.h"
12
13 namespace base {
14
15 IOPMPowerSourceSamplingEventSource::IOPMPowerSourceSamplingEventSource() =
16 default;
17
18 IOPMPowerSourceSamplingEventSource::~IOPMPowerSourceSamplingEventSource() =
19 default;
20
Start(SamplingEventCallback callback)21 bool IOPMPowerSourceSamplingEventSource::Start(SamplingEventCallback callback) {
22 DCHECK(!callback_);
23 DCHECK(callback);
24
25 callback_ = callback;
26
27 service_.reset(IOServiceGetMatchingService(
28 kIOMasterPortDefault, IOServiceMatching("IOPMPowerSource")));
29
30 if (!service_) {
31 VLOG(1) << "IOPMPowerSource service not found. This is expected on desktop "
32 "Macs.";
33 return false;
34 }
35
36 notify_port_.reset(IONotificationPortCreate(kIOMasterPortDefault));
37 if (!notify_port_.is_valid()) {
38 LOG(ERROR) << "Could not create a notification port";
39 return false;
40 }
41
42 IONotificationPortSetDispatchQueue(notify_port_.get(),
43 dispatch_get_main_queue());
44
45 kern_return_t result = IOServiceAddInterestNotification(
46 notify_port_.get(), service_, kIOGeneralInterest, OnNotification, this,
47 notification_.InitializeInto());
48
49 if (result != KERN_SUCCESS) {
50 LOG(ERROR) << "Could not register to IOPMPowerSource notifications";
51 return false;
52 }
53
54 return true;
55 }
56
57 // static
OnNotification(void * context,io_service_t service,natural_t message_type,void * message_argument)58 void IOPMPowerSourceSamplingEventSource::OnNotification(
59 void* context,
60 io_service_t service,
61 natural_t message_type,
62 void* message_argument) {
63 IOPMPowerSourceSamplingEventSource* self =
64 static_cast<IOPMPowerSourceSamplingEventSource*>(context);
65 self->callback_.Run();
66 }
67
68 } // namespace base
69