2 * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 // powerwatch - hook into system notifications of power events
28 #include "powerwatch.h"
29 #include <IOKit/IOMessage.h>
33 namespace MachPlusPlus
{
37 // The obligatory empty virtual destructor
39 PowerWatcher::~PowerWatcher()
44 // The default NULL implementations of the callback virtuals.
45 // We define these (rather than leaving them abstract) since
46 // many users want only one of these events.
48 void PowerWatcher::systemWillSleep()
51 void PowerWatcher::systemIsWaking()
54 void PowerWatcher::systemWillPowerDown()
57 void PowerWatcher::systemWillPowerOn()
65 IOPowerWatcher::iopmcallback(void * param
,
66 IOPMConnection connection
,
67 IOPMConnectionMessageToken token
,
68 IOPMSystemPowerStateCapabilities capabilities
)
70 IOPowerWatcher
*me
= (IOPowerWatcher
*)param
;
72 if (SECURITY_DEBUG_LOG_ENABLED()) {
73 secdebug("powerwatch", "powerstates");
74 if (capabilities
& kIOPMSystemPowerStateCapabilityDisk
)
75 secdebug("powerwatch", "disk");
76 if (capabilities
& kIOPMSystemPowerStateCapabilityNetwork
)
77 secdebug("powerwatch", "net");
78 if (capabilities
& kIOPMSystemPowerStateCapabilityAudio
)
79 secdebug("powerwatch", "audio");
80 if (capabilities
& kIOPMSystemPowerStateCapabilityVideo
)
81 secdebug("powerwatch", "video");
84 /* if cpu and no display -> in DarkWake */
85 if ((capabilities
& (kIOPMSystemPowerStateCapabilityCPU
|kIOPMSystemPowerStateCapabilityVideo
)) == kIOPMSystemPowerStateCapabilityCPU
) {
86 secdebug("powerwatch", "enter DarkWake");
87 me
->mInDarkWake
= true;
88 } else if (me
->mInDarkWake
) {
89 secdebug("powerwatch", "exit DarkWake");
90 me
->mInDarkWake
= false;
93 (void)IOPMConnectionAcknowledgeEvent(connection
, token
);
100 IOPowerWatcher::setupDarkWake()
106 mIOPMqueue
= dispatch_queue_create("com.apple.security.IOPowerWatcher", NULL
);
107 if (mIOPMqueue
== NULL
)
110 ret
= ::IOPMConnectionCreate(CFSTR("IOPowerWatcher"),
111 kIOPMSystemPowerStateCapabilityDisk
112 | kIOPMSystemPowerStateCapabilityNetwork
113 | kIOPMSystemPowerStateCapabilityAudio
114 | kIOPMSystemPowerStateCapabilityVideo
,
116 if (ret
!= kIOReturnSuccess
)
119 ret
= ::IOPMConnectionSetNotification(mIOPMconn
, this,
120 (IOPMEventHandlerType
)iopmcallback
);
121 if (ret
!= kIOReturnSuccess
)
124 ::IOPMConnectionSetDispatchQueue(mIOPMconn
, mIOPMqueue
);
127 IOPowerWatcher::IOPowerWatcher()
129 if (!(mKernelPort
= ::IORegisterForSystemPower(this, &mPortRef
, ioCallback
, &mHandle
)))
130 UnixError::throwMe(EINVAL
); // no clue
135 IOPowerWatcher::~IOPowerWatcher()
138 ::IODeregisterForSystemPower(&mHandle
);
141 ::IOPMConnectionSetDispatchQueue(mIOPMconn
, NULL
);
142 ::IOPMConnectionRelease(mIOPMconn
);
145 ::dispatch_release(mIOPMqueue
);
150 // The callback dispatcher
152 void IOPowerWatcher::ioCallback(void *refCon
, io_service_t service
,
153 natural_t messageType
, void *argument
)
155 IOPowerWatcher
*me
= (IOPowerWatcher
*)refCon
;
156 enum { allow
, refuse
, ignore
} reaction
;
157 switch (messageType
) {
158 case kIOMessageSystemWillSleep
:
159 secdebug("powerwatch", "system will sleep");
160 me
->systemWillSleep();
163 case kIOMessageSystemHasPoweredOn
:
164 secdebug("powerwatch", "system has powered on");
165 me
->systemIsWaking();
168 case kIOMessageSystemWillPowerOff
:
169 secdebug("powerwatch", "system will power off");
170 me
->systemWillPowerDown();
173 case kIOMessageSystemWillNotPowerOff
:
174 secdebug("powerwatch", "system will not power off");
177 case kIOMessageCanSystemSleep
:
178 secdebug("powerwatch", "can system sleep");
181 case kIOMessageSystemWillNotSleep
:
182 secdebug("powerwatch", "system will not sleep");
185 case kIOMessageCanSystemPowerOff
:
186 secdebug("powerwatch", "can system power off");
189 case kIOMessageSystemWillPowerOn
:
190 secdebug("powerwatch", "system will power on");
191 me
->systemWillPowerOn();
195 secdebug("powerwatch",
196 "type 0x%x message received (ignored)", messageType
);
201 // handle acknowledgments
204 secdebug("powerwatch", "calling IOAllowPowerChange");
205 IOAllowPowerChange(me
->mKernelPort
, long(argument
));
208 secdebug("powerwatch", "calling IOCancelPowerChange");
209 IOCancelPowerChange(me
->mKernelPort
, long(argument
));
212 secdebug("powerwatch", "sending no response");
219 // The MachServer hookup
221 PortPowerWatcher::PortPowerWatcher()
223 port(IONotificationPortGetMachPort(mPortRef
));
226 boolean_t
PortPowerWatcher::handle(mach_msg_header_t
*in
)
228 IODispatchCalloutFromMessage(NULL
, in
, mPortRef
);
233 } // end namespace MachPlusPlus
235 } // end namespace Security