Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(550)

Side by Side Diff: base/power_monitor/power_monitor_device_source_mac.mm

Issue 2351593004: Implement base::PowerMonitor::IsOnBatteryPower() for OSX. (Closed)
Patch Set: Invert setter. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Implementation based on sample code from 5 // Implementation based on sample code from
6 // http://developer.apple.com/library/mac/#qa/qa1340/_index.html. 6 // http://developer.apple.com/library/mac/#qa/qa1340/_index.html.
7 7
8 #include "base/power_monitor/power_monitor_device_source.h" 8 #include "base/power_monitor/power_monitor_device_source.h"
9 9
10 #include "base/mac/foundation_util.h"
11 #include "base/mac/scoped_cftyperef.h"
10 #include "base/power_monitor/power_monitor.h" 12 #include "base/power_monitor/power_monitor.h"
11 #include "base/power_monitor/power_monitor_source.h" 13 #include "base/power_monitor/power_monitor_source.h"
12 14
13 #include <IOKit/IOMessage.h> 15 #include <IOKit/IOMessage.h>
16 #include <IOKit/ps/IOPSKeys.h>
17 #include <IOKit/ps/IOPowerSources.h>
14 #include <IOKit/pwr_mgt/IOPMLib.h> 18 #include <IOKit/pwr_mgt/IOPMLib.h>
15 19
16 namespace base { 20 namespace base {
17 21
18 void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) { 22 void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) {
19 PowerMonitorSource::ProcessPowerEvent(event); 23 PowerMonitorSource::ProcessPowerEvent(event);
20 } 24 }
21 25
26 bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
27 base::ScopedCFTypeRef<CFTypeRef> info(IOPSCopyPowerSourcesInfo());
28 base::ScopedCFTypeRef<CFArrayRef> power_sources_list(
29 IOPSCopyPowerSourcesList(info));
30
31 const CFIndex count = CFArrayGetCount(power_sources_list);
32 for (CFIndex i = 0; i < count; ++i) {
33 const CFDictionaryRef description = IOPSGetPowerSourceDescription(
34 info, CFArrayGetValueAtIndex(power_sources_list, i));
35 if (!description)
36 continue;
37
38 CFStringRef current_state = base::mac::GetValueFromDictionary<CFStringRef>(
39 description, CFSTR(kIOPSPowerSourceStateKey));
40
41 if (!current_state)
42 continue;
43
44 // We only report "on battery power" if no source is on AC power.
45 if (CFStringCompare(current_state, CFSTR(kIOPSBatteryPowerValue), 0) !=
46 kCFCompareEqualTo) {
47 return false;
48 }
49 }
50
51 return true;
52 }
53
22 namespace { 54 namespace {
23 55
24 io_connect_t g_system_power_io_port = 0; 56 io_connect_t g_system_power_io_port = 0;
25 IONotificationPortRef g_notification_port_ref = 0; 57 IONotificationPortRef g_notification_port_ref = 0;
26 io_object_t g_notifier_object = 0; 58 io_object_t g_notifier_object = 0;
59 CFRunLoopSourceRef g_battery_status_ref = 0;
Robert Sesek 2016/09/26 22:21:19 ... like these could be member variables instead o
60
61 void BatteryEventCallback(void*) {
62 ProcessPowerEventHelper(PowerMonitorSource::POWER_STATE_EVENT);
63 }
27 64
28 void SystemPowerEventCallback(void*, 65 void SystemPowerEventCallback(void*,
29 io_service_t service, 66 io_service_t service,
30 natural_t message_type, 67 natural_t message_type,
31 void* message_argument) { 68 void* message_argument) {
32 switch (message_type) { 69 switch (message_type) {
33 // If this message is not handled the system may delay sleep for 30 seconds. 70 // If this message is not handled the system may delay sleep for 30 seconds.
34 case kIOMessageCanSystemSleep: 71 case kIOMessageCanSystemSleep:
35 IOAllowPowerChange(g_system_power_io_port, 72 IOAllowPowerChange(g_system_power_io_port,
36 reinterpret_cast<intptr_t>(message_argument)); 73 reinterpret_cast<intptr_t>(message_argument));
(...skipping 29 matching lines...) Expand all
66 DCHECK_NE(g_system_power_io_port, 0u); 103 DCHECK_NE(g_system_power_io_port, 0u);
67 } 104 }
68 105
69 void PowerMonitorDeviceSource::PlatformInit() { 106 void PowerMonitorDeviceSource::PlatformInit() {
70 // Need to call AllocateSystemIOPorts() before creating a PowerMonitor 107 // Need to call AllocateSystemIOPorts() before creating a PowerMonitor
71 // object. 108 // object.
72 DCHECK_NE(g_system_power_io_port, 0u); 109 DCHECK_NE(g_system_power_io_port, 0u);
73 if (g_system_power_io_port == 0) 110 if (g_system_power_io_port == 0)
74 return; 111 return;
75 112
76 // Add the notification port to the application runloop 113 // Add the notification port and battery monitor to the application runloop
77 CFRunLoopAddSource( 114 CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(
78 CFRunLoopGetCurrent(), 115 g_notification_port_ref),
79 IONotificationPortGetRunLoopSource(g_notification_port_ref), 116 kCFRunLoopCommonModes);
80 kCFRunLoopCommonModes); 117
118 base::ScopedCFTypeRef<CFRunLoopSourceRef> battery_status_ref(
119 IOPSNotificationCreateRunLoopSource(BatteryEventCallback, nullptr));
120 CFRunLoopAddSource(CFRunLoopGetCurrent(), battery_status_ref,
121 kCFRunLoopDefaultMode);
122 g_battery_status_ref = battery_status_ref.release();
81 } 123 }
82 124
83 void PowerMonitorDeviceSource::PlatformDestroy() { 125 void PowerMonitorDeviceSource::PlatformDestroy() {
84 DCHECK_NE(g_system_power_io_port, 0u); 126 DCHECK_NE(g_system_power_io_port, 0u);
85 if (g_system_power_io_port == 0) 127 if (g_system_power_io_port == 0)
86 return; 128 return;
87 129
88 // Remove the sleep notification port from the application runloop 130 // Remove the sleep notification port from the application runloop
89 CFRunLoopRemoveSource( 131 CFRunLoopRemoveSource(
90 CFRunLoopGetCurrent(), 132 CFRunLoopGetCurrent(),
91 IONotificationPortGetRunLoopSource(g_notification_port_ref), 133 IONotificationPortGetRunLoopSource(g_notification_port_ref),
92 kCFRunLoopCommonModes); 134 kCFRunLoopCommonModes);
93 135
136 base::ScopedCFTypeRef<CFRunLoopSourceRef> battery_status_ref(
137 g_battery_status_ref);
138 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), g_battery_status_ref,
139 kCFRunLoopDefaultMode);
140 g_battery_status_ref = 0;
141
94 // Deregister for system sleep notifications 142 // Deregister for system sleep notifications
95 IODeregisterForSystemPower(&g_notifier_object); 143 IODeregisterForSystemPower(&g_notifier_object);
96 144
97 // IORegisterForSystemPower implicitly opens the Root Power Domain IOService, 145 // IORegisterForSystemPower implicitly opens the Root Power Domain IOService,
98 // so we close it here. 146 // so we close it here.
99 IOServiceClose(g_system_power_io_port); 147 IOServiceClose(g_system_power_io_port);
100 148
101 g_system_power_io_port = 0; 149 g_system_power_io_port = 0;
102 150
103 // Destroy the notification port allocated by IORegisterForSystemPower. 151 // Destroy the notification port allocated by IORegisterForSystemPower.
104 IONotificationPortDestroy(g_notification_port_ref); 152 IONotificationPortDestroy(g_notification_port_ref);
105 } 153 }
106 154
107 } // namespace base 155 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698