+void IOService::consoleLockTimer(thread_call_param_t p0, thread_call_param_t p1)
+{
+ IOService::updateConsoleUsers(NULL, 0);
+}
+
+void IOService::updateConsoleUsers(OSArray * consoleUsers, IOMessage systemMessage)
+{
+ IORegistryEntry * regEntry;
+ OSObject * locked = kOSBooleanFalse;
+ uint32_t idx;
+ bool loggedIn;
+ bool publish;
+ OSDictionary * user;
+ static IOMessage sSystemPower;
+
+ regEntry = IORegistryEntry::getRegistryRoot();
+
+ IOLockLock(gIOConsoleUsersLock);
+
+ if (systemMessage)
+ {
+ sSystemPower = systemMessage;
+ }
+ loggedIn = false;
+ if (consoleUsers)
+ {
+ OSNumber * num = 0;
+ for (idx = 0;
+ (user = OSDynamicCast(OSDictionary, consoleUsers->getObject(idx)));
+ idx++)
+ {
+ loggedIn |= ((kOSBooleanTrue == user->getObject(gIOConsoleSessionOnConsoleKey))
+ && (kOSBooleanTrue == user->getObject(gIOConsoleSessionLoginDoneKey)));
+ if (!num)
+ {
+ num = OSDynamicCast(OSNumber, user->getObject(gIOConsoleSessionScreenLockedTimeKey));
+ }
+ }
+ gIOConsoleLockTime = num ? num->unsigned32BitValue() : 0;
+ }
+
+ if (!loggedIn
+ || (kIOMessageSystemWillSleep == sSystemPower)
+ || (kIOMessageSystemPagingOff == sSystemPower))
+ {
+ locked = kOSBooleanTrue;
+ }
+ else if (gIOConsoleLockTime)
+ {
+ clock_sec_t now;
+ clock_usec_t microsecs;
+
+ clock_get_calendar_microtime(&now, µsecs);
+ if (gIOConsoleLockTime > now)
+ {
+ AbsoluteTime deadline;
+ clock_interval_to_deadline(gIOConsoleLockTime - now, kSecondScale, &deadline);
+ thread_call_enter_delayed(gIOConsoleLockCallout, deadline);
+ }
+ else
+ {
+ locked = kOSBooleanTrue;
+ }
+ }
+
+ publish = (consoleUsers || (locked != regEntry->getProperty(gIOConsoleLockedKey)));
+ if (publish)
+ {
+ regEntry->setProperty(gIOConsoleLockedKey, locked);
+ if (consoleUsers)
+ {
+ regEntry->setProperty(gIOConsoleUsersKey, consoleUsers);
+ }
+ OSIncrementAtomic( &gIOConsoleUsersSeed );
+ }
+
+ IOLockUnlock(gIOConsoleUsersLock);
+
+ if (publish)
+ {
+ publishResource( gIOConsoleUsersSeedKey, gIOConsoleUsersSeedValue );
+
+ MessageClientsContext context;
+
+ context.service = getServiceRoot();
+ context.type = kIOMessageConsoleSecurityChange;
+ context.argument = (void *) regEntry;
+ context.argSize = 0;
+
+ applyToInterestNotifiers(getServiceRoot(), gIOConsoleSecurityInterest,
+ &messageClientsApplier, &context );
+ }
+}
+