1/*
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * Copyright (c) 2002 Apple Computer, Inc.  All rights reserved.
25 *
26 * HISTORY
27 *
28 * 29-Aug-02 ebold created
29 *
30 */
31#ifndef _PMAssertions_h_
32#define _PMAssertions_h_
33
34#include <IOKit/pwr_mgt/IOPM.h>
35#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
36
37#include <sys/queue.h>
38
39#define IOREPORT_ABORT(str...) \
40do {    \
41    asl_log(0,0,ASL_LEVEL_ERR, (str));  \
42    abort(); \
43} while(0)
44
45
46#include <IOKit/IOReportMacros.h>
47#include <IOKit/IOReportTypes.h>
48
49/* ExternalMedia assertion
50 * This assertion is only defined here in PM configd.
51 * It can only be asserted by PM configd; not by other user processes.
52 */
53#define _kIOPMAssertionTypeExternalMediaCStr    "ExternalMedia"
54#define _kIOPMAssertionTypeExternalMedia        CFSTR(_kIOPMAssertionTypeExternalMediaCStr)
55
56
57#ifndef     kIOPMRootDomainWakeTypeNetwork
58#define     kIOPMRootDomainWakeTypeNetwork          CFSTR("Network")
59#endif
60
61#ifndef     kIOPMRootDomainWakeTypeAlarm
62#define     kIOPMRootDomainWakeTypeAlarm            CFSTR("Alarm")
63#endif
64
65#ifndef     kIOPMRootDomainWakeTypeMaintenance
66#define     kIOPMRootDomainWakeTypeMaintenance      CFSTR("Maintenance")
67#endif
68
69#ifndef     kIOPMRootDomainWakeTypeSleepTimer
70#define     kIOPMRootDomainWakeTypeSleepTimer       CFSTR("SleepTimer")
71#endif
72
73#ifndef kIOPMRootDomainWakeTypeSleepService
74#define kIOPMRootDomainWakeTypeSleepService         CFSTR("SleepService")
75#endif
76
77#ifndef kIOPMRootDomainWakeReasonRTC
78#define  kIOPMRootDomainWakeReasonRTC        CFSTR("RTC")
79#endif
80
81#ifndef kIORootDomainWakeReasonDarkPME
82#define kIORootDomainWakeReasonDarkPME          CFSTR("EC.DarkPME")
83#endif
84
85#ifndef kIOPMrootDomainWakeTypeLowBattery
86#define kIOPMrootDomainWakeTypeLowBattery   CFSTR("LowBattery")
87#endif
88
89#ifndef kIOPMRootDomainWakeTypeNotification
90#define kIOPMRootDomainWakeTypeNotification CFSTR("Notification")
91#endif
92
93#define ID_FROM_INDEX(idx)          (idx + 300)
94#define INDEX_FROM_ID(id)           (id - 300)
95
96#define MAKE_UNIQAID(time, type, idx) \
97    ((((uint64_t)time) & 0xffffffff) << 32) | ((type) & 0xffff) << 16 | ((idx) & 0xffff)
98
99/*
100 * A 'assertion_t' stucture is created for each assertion created by the processes.
101 *
102 * Each assertion will be associated with one of the pre-defined assertion types. All
103 * assertion types are defined in kerAssertionType enum. A 'assertionType_t' strcture is
104 * created for each assertion type at the start of the process and can be accessed from
105 * 'gAssertionTypes' array.
106 *
107 * Each assertion type will have a pre-defined effect on the system. All possible effects are
108 * listed in 'kerAssertionEffect' enum. A 'assertionEffect_t' structure is created for each
109 * assertion effect at the start of the process and can be accessed from 'gAssertionEffects'
110 * array.
111 *
112 * An assertion type can change the effect it has on the system based on various conditions
113 * like power source, wake type, user settings etc. When an assertion type's effect changes,
114 * it is moved from assertionEffect_t structure to another one.
115 */
116typedef enum {
117    kNoEffect                       = 0,
118    kPrevIdleSlpEffect,
119    kPrevDemandSlpEffect,
120    kPrevDisplaySlpEffect,  // Stats are maintained for effects up to this one
121
122    kExternalMediaEffect,
123    kPreventDiskSleepEffect,
124    kTicklessDisplayWakeEffect,
125
126    kEnableIdleEffect,
127    kHighPerfEffect,
128    kDisableInflowEffect,
129    kInhibitChargeEffect,
130    kDisableWarningsEffect,
131    kNoRealPowerSourcesDebugEffect,
132
133    kMaxAssertionEffects
134} kerAssertionEffect;
135
136// Stats are maintained only for affects up to kPrevDisplaySlpEffect
137#define kMaxEffectStats     kPrevDisplaySlpEffect+1
138
139
140/* IOPMAssertion levels
141 *
142 * Each assertion type has a corresponding bitfield index, here.
143 * Also as found under the "Bitfields" property in assertion CFDictionaries.
144 */
145typedef enum {
146    // These must be consecutive integers beginning at 0
147    kHighPerfType                   = 0,
148    kPreventIdleType                = 1,
149    kDisableInflowType              = 2,
150    kInhibitChargeType              = 3,
151    kDisableWarningsType            = 4,
152    kPreventDisplaySleepType        = 5,
153    kEnableIdleType                 = 6,
154    kPreventSleepType               = 7,
155    kExternalMediaType              = 8,
156    kDeclareUserActivityType        = 9,
157    kPushServiceTaskType            = 10,
158    kBackgroundTaskType             = 11,
159    kDeclareSystemActivityType      = 12,
160    kSRPreventSleepType             = 13, /* Silent running Prevent Sleep, used as internal proxy */
161    kTicklessDisplayWakeType        = 14, /* Display wake without HID tick */
162    kPreventDiskSleepType           = 15,
163    kIntPreventDisplaySleepType     = 16, /* Prevent display sleep, used as internal proxy */
164    kNetworkAccessType              = 17, /* Prevent demand sleep on AC, prevent idle sleep on batt */
165    kInteractivePushServiceType     = 18,
166    kReservePwrPreventIdleType      = 19, /* Prevents idle sleep in reserve power mode */
167
168
169    // Make sure this is the last enum element, as it tells us the total
170    // number of elements in the enum definition
171    kIOPMNumAssertionTypes
172} kerAssertionType;
173
174/*
175 * effectStats_t
176 *
177 * This structure accumulates the total duration for which a process is
178 * holding each assertion effect.
179 */
180typedef struct {
181    uint32_t    cnt;            // Number of assertions of this effect currently held
182    uint64_t    startTime;      // Time at which first assertion is taken after last reset
183} effectStats_t;
184
185typedef struct {
186#if !TARGET_OS_EMBEDDED
187    uint8_t    assert_cnt [kIOPMNumAssertionTypes];  // Number of assertions of each type.
188                                                     // Set only for app sleep preventing assertions
189    uint32_t   aggTypes;                             // Aggregate assertion types of this proc.
190                                                     // Set only for app sleep preventing assertions
191#endif
192    effectStats_t       stats[kMaxEffectStats]; // Stats per assertion effect
193    void                *reportBuf;                  // Stats buffer for IOReporter
194
195    uint32_t            retain_cnt;     // Retain cnt of this structure
196    CFStringRef         name;           // Process name
197    dispatch_source_t   disp_src;       // Dispatch src to handle process exit
198    pid_t               pid;            // PID
199    uint32_t            create_seq;
200    uint32_t            anychange:1;    // Interested in any assertion changes notification
201    uint32_t            aggchange:1;    // Interested in assertion aggregates change notifications
202    uint32_t            timeoutchange:1;    // Interested in assertion timeout notification
203    uint32_t            disableAS_pend:1;   // Disable AppSleep notification need to be sent
204    uint32_t            enableAS_pend:1;    // Enable AppSleep notification need to be sent
205} ProcessInfo;
206
207typedef struct assertion {
208    LIST_ENTRY(assertion) link;
209    CFMutableDictionaryRef props;       // client provided properties
210    uint32_t        state;              // assertion state bits
211    uint64_t        createTime;         // Time at which assertion is created
212    uint64_t        timeout;            // absolute time at which assertion will timeout
213
214    kerAssertionType    kassert;        // Assertion type, also index into gAssertionTypes
215    IOPMAssertionID     assertionId;    // Assertion Id returned to client
216
217    uint32_t        mods;               // Modifcation bits for most recent SetProperties call
218
219    uint32_t        retainCnt;          // Number of retain calls
220
221    ProcessInfo     *pinfo;             // Pointer to ProcessInfo structure
222
223    pid_t           causingPid;         // PID for process on whose behalf this assertion is raised
224    ProcessInfo     *causingPinfo;      // Corresponding ProcessInfo struct
225} assertion_t;
226
227/* State bits for assertion_t structure */
228#define kAssertionStateTimed                0x01
229#define kAssertionStateInactive             0x02
230#define kAssertionStateValidOnBatt          0x04
231#define kAssertionLidStateModifier          0x08
232#define kAssertionTimeoutIsSystemTimer      0x10  // Assertion timeout value changes with system idle/display sleep timer
233#define kAssertionSkipLogging               0x20  // Avoid logging this assertion, even if type is set to kAssertionTypeLogOnCreate
234#define kAssertionStateLogged               0x40
235#define kAssertionStateAddsToProcStats      0x80
236
237/* Mods bits for assertion_t structure */
238#define kAssertionModTimer              0x1
239#define kAssertionModLevel              0x2
240#define kAssertionModType               0x4
241#define kAssertionModPowerConstraint    0x8
242#define kAssertionModLidState           0x10
243
244typedef enum {
245    kAssertionOpRaise,
246    kAssertionOpRelease,
247    kAssertionOpEval,    // Evaluate for any changes to be sent to kernel due to enviromental changes
248    kAssertionOpGlobalTimeout
249} assertionOps;
250
251
252typedef struct assertionType assertionType_t;
253typedef void (*assertionHandler_f)(assertionType_t *a, assertionOps op);
254
255typedef struct {
256    LIST_HEAD(, assertionType)  assertTypes;
257    kerAssertionEffect  effectIdx;
258} assertionEffect_t;
259
260/* Structure per kernel assertion type */
261struct assertionType {
262    uint32_t        flags;              /* Specific to this assertion type */
263
264    LIST_HEAD(, assertion) activeTimed;  /* Active assertions with timeout */
265    LIST_HEAD(, assertion) active;       /* Active assertions without timeout */
266    LIST_HEAD(, assertion) inactive;     /* timed out assertions/Level 0 assertions etc */
267
268    kerAssertionType    kassert;
269    dispatch_source_t   timer;          /* dispatch source for Per assertion timer */
270    dispatch_source_t   globalTimer;    /* dispatch source for all assertions of this type */
271
272    CFStringRef     entitlement;        /* if set, caller must have this entitlement to create this assertion */
273    uint64_t        globalTimeout;      /* Relative time at which assertion is timedout */
274    uint32_t        forceTimedoutCnt;   /* Count of assertions turned off due to global timer */
275    CFStringRef     uuid;               /* Assertion type specific UUID */
276    uint64_t        autoTimeout;        /* Automatic timeout for each assertion;set with kAssertionTypeAutoTimed flag */
277
278    kerAssertionEffect   effectIdx;
279    LIST_ENTRY(assertionType)    link;
280    assertionHandler_f  handler;        /* Function changing the required settings in the kernel for this assertion type */
281
282    uint32_t            disableCnt;     /* Number of active disable requests for this type */
283    CFArrayRef          procs;          /* ProcessInfo of processes holding this assertion type */
284
285    // Fields changed by properties set on assertion.
286    // Not all fields are valid for all assertion types
287    uint32_t   validOnBattCount;        /* Count of assertions requesting to be active on Battery power */
288    uint32_t   lidSleepCount;           /* Count of assertions changing clamshellSleep state(For kDeclareUserActivityType only) */
289} ;
290
291/* Flag bits for assertionType_t structure */
292#define kAssertionTypeNotValidOnBatt        0x01     /* By default, this assertion type is not valid on battery power */
293#define kAssertionTypeGloballyTimed         0x02     /* A global timer releases all assertions of this type */
294#define kAssertionTypeDisabled              0x04     /* All assertion requests of this type are ignored */
295#define kAssertionTypePreventAppSleep       0x08     /* App sleep is prevented when this assertion type is raised by app */
296#define kAssertionTypeAutoTimed             0x10     /* Each assertion of this type automatically gets a timeout value */
297#define kAssertionTypeLogOnCreate           0x20     /* Assertions of this type have to be logged on creation */
298
299/* Assertion logging actions */
300typedef enum {
301    kACreateLog,
302    kACreateRetain,
303    kAReleaseLog,
304    kAClientDeathLog,
305    kATimeoutLog,
306    kACapExpiryLog,
307    kASummaryLog,
308    kATurnOffLog,
309    kATurnOnLog
310} assertLogAction;
311
312__private_extern__ void PMAssertions_prime(void);
313__private_extern__ void createOnBootAssertions(void);
314__private_extern__ void PMAssertions_SettingsHaveChanged(void);
315
316__private_extern__ IOReturn _IOPMSetActivePowerProfilesRequiresRoot(
317                                CFDictionaryRef which_profile,
318                                int uid,
319                                int gid);
320
321__private_extern__ IOReturn _IOPMAssertionCreateRequiresRoot(
322                                mach_port_t task_port,
323                                char *nameCStr,
324                                char *assertionCStr,
325                                int level,
326                                int *assertion_id);
327
328__private_extern__ void _TaskPortInvalidatedCallout(CFMachPortRef port, void *info);
329
330__private_extern__ void _PMAssertionsDriverAssertionsHaveChanged(uint32_t changedDriverAssertions);
331
332__private_extern__ void _ProxyAssertions(const struct IOPMSystemCapabilityChangeParameters *capArgs);
333
334
335__private_extern__ void PMAssertions_TurnOffAssertions_ApplePushServiceTask(void);
336
337__private_extern__ IOReturn InternalCreateAssertion(
338                                CFMutableDictionaryRef properties,
339                                IOPMAssertionID *outID);
340
341__private_extern__ void InternalReleaseAssertion(
342                                IOPMAssertionID *outID);
343
344__private_extern__ void InternalEvaluateAssertions(void);
345
346__private_extern__ void evalAllUserActivityAssertions(unsigned int dispSlpTimer);
347__private_extern__ void evalAllNetworkAccessAssertions();
348
349__private_extern__ CFMutableDictionaryRef	_IOPMAssertionDescriptionCreate(
350                            CFStringRef AssertionType,
351                            CFStringRef Name,
352                            CFStringRef Details,
353                            CFStringRef HumanReadableReason,
354                            CFStringRef LocalizationBundlePath,
355                            CFTimeInterval Timeout,
356                            CFStringRef TimeoutBehavior);
357
358
359__private_extern__ CFStringRef processInfoGetName(pid_t p);
360__private_extern__ void setSleepServicesTimeCap(uint32_t  timeoutInMS);
361__private_extern__ bool systemBlockedInS0Dark( );
362__private_extern__ bool checkForActivesByType(kerAssertionType type);
363__private_extern__ bool checkForEntriesByType(kerAssertionType type);
364__private_extern__ void disableAssertionType(kerAssertionType type);
365__private_extern__ void enableAssertionType(kerAssertionType type);
366__private_extern__ void applyToAllAssertionsSync(assertionType_t *assertType,
367      bool applyToInactives,  void (^performOnAssertion)(assertion_t *));
368__private_extern__ void configAssertionType(kerAssertionType idx, bool initialConfig);
369__private_extern__ void logAssertionEvent(assertLogAction assertionAction, assertion_t *assertion);
370__private_extern__ uint8_t getAssertionLevel(kerAssertionType idx);
371__private_extern__ void setAggregateLevel(kerAssertionType idx, uint8_t val);
372__private_extern__ uint32_t getKerAssertionBits( );
373__private_extern__ void setAssertionActivityLog(int value);
374__private_extern__ void setAssertionActivityAggregate(int value);
375__private_extern__ kern_return_t setReservePwrMode(int enable);
376
377__private_extern__ void logASLAllAssertions( );
378
379#if !TARGET_OS_EMBEDDED
380
381__private_extern__ void logASLAssertionTypeSummary( kerAssertionType type);
382
383#endif
384
385
386#endif
387