• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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