/// <summary> /// Raises the system will sleep event. /// </summary> /// <param name="args">The arguments to send for the event.</param> protected virtual void OnSystemWillSleep(SystemWillSleepEventArgs args) { DebugOutput("IOServer.SerialPortNotifier raising: OnSystemWillSleep: CanCancel: " + args.CanCancel); var systemWillSleep = SystemWillSleep; if (systemWillSleep != null) { systemWillSleep(this, args); } }
private static void HandleSystemWillSleep(object sender, SystemWillSleepEventArgs e) { DebugOutput("DeviceMonitor.HandleSystemWillSleep CanCancel: " + e.CanCancel + " PreventSystemSleepDuringDeviceCommands: " + Properties.Settings.Default.PreventSystemSleepDuringDeviceCommands); var cancelSleep = false; if (e.CanCancel && Properties.Settings.Default.PreventSystemSleepDuringDeviceCommands) { var portBeingUsed = GetDevices().FirstOrDefault(d => d.IsValid && (d.Port != null) && d.Port.IsOpen && d.Port.IsInUse); cancelSleep = portBeingUsed != null; e.Cancel = cancelSleep; DebugOutput("DeviceMonitor.HandleSystemWillSleep will cancel: " + cancelSleep + " port being used: " + (cancelSleep ? portBeingUsed.Name : "<null>")); } if (!cancelSleep) { foreach (var port in INTV.Shared.Model.Device.SerialPortConnection.AvailablePorts) { DeviceChange.SystemReportsDeviceRemoved(null, port, INTV.Core.Model.Device.ConnectionType.Serial); } } }
// see https://developer.apple.com/library/content/qa/qa1340/_index.html // see https://developer.apple.com/documentation/iokit/1557114-ioregisterforsystempower?preferredLanguage=occ private static void SystemPowerInterestCallback(IntPtr refcon, IntPtr service, uint messageType, IntPtr messageArgument) { var message = (IOMessage)messageType; DebugOutput("IOService: SystemPowerInterestCallback: " + message); var refconObject = (NSObject)Runtime.GetNSObject(refcon); var serialPortNotifier = refconObject as IOKitNotificationPort; switch (message) { case IOMessage.KIOMessageCanSystemSleep: // From documentation for IORegisterForSystemPower // ----------------------------------------------- // Indicates the system is pondering an idle sleep, but gives apps the chance to veto that sleep attempt. // Caller must acknowledge kIOMessageCanSystemSleep by calling IOAllowPowerChange or IOCancelPowerChange. // Calling IOAllowPowerChange will not veto the sleep; any app that calls IOCancelPowerChange will veto // the idle sleep. A kIOMessageCanSystemSleep notification will be followed up to 30 seconds later by // a kIOMessageSystemWillSleep message, or a kIOMessageSystemWillNotSleep message. // ----------------------------------------------- // From example code: // ------------------ // Idle sleep is about to kick in. This message will not be sent for forced sleep. // Applications have a chance to prevent sleep by calling IOCancelPowerChange. // Most applications should not prevent idle sleep. // Power Management waits up to 30 seconds for you to either allow or deny idle // sleep. If you don't acknowledge this power change by calling either // IOAllowPowerChange or IOCancelPowerChange, the system will wait 30 // seconds then go to sleep. // ------------------ var systemWillSleepArgs = new SystemWillSleepEventArgs(canCancel: true); serialPortNotifier.OnSystemWillSleep(systemWillSleepArgs); DebugOutput("IOService: SystemPowerInterestCallback: " + message + " CancelSleep: " + systemWillSleepArgs.Cancel); if (systemWillSleepArgs.Cancel) { serialPortNotifier.IOConnectionPort.CancelPowerChange((nint)messageArgument); } else { serialPortNotifier.IOConnectionPort.AllowPowerChange((nint)messageArgument); } break; case IOMessage.KIOMessageSystemWillSleep: // From documentation for IORegisterForSystemPower // ----------------------------------------------- // Delivered at the point the system is initiating a non-abortable sleep. // Callers MUST acknowledge this event by calling IOAllowPowerChange. // If a caller does not acknowledge the sleep notification, the sleep will continue anyway // after a 30 second timeout (resulting in bad user experience). Delivered before any // hardware is powered off. // ----------------------------------------------- // From example code: // ------------------ // The system WILL go to sleep. If you do not call IOAllowPowerChange or // IOCancelPowerChange to acknowledge this message, sleep will be // delayed by 30 seconds. // NOTE: If you call IOCancelPowerChange to deny sleep it returns // kIOReturnSuccess, however the system WILL still go to sleep. // ------------------ serialPortNotifier.OnSystemWillSleep(new SystemWillSleepEventArgs(canCancel: false)); serialPortNotifier.IOConnectionPort.AllowPowerChange((nint)messageArgument); break; case IOMessage.KIOMessageSystemWillNotSleep: // From documentation for IORegisterForSystemPower // ----------------------------------------------- // Delivered when some app client has vetoed an idle sleep request. // kIOMessageSystemWillNotSleep may follow a kIOMessageCanSystemSleep notification, // but will not otherwise be sent. Caller must NOT acknowledge kIOMessageSystemWillNotSleep; // the caller must simply return from its handler. // ----------------------------------------------- break; case IOMessage.KIOMessageSystemWillPowerOn: // From documentation for IORegisterForSystemPower // ----------------------------------------------- // Delivered at early wakeup time, before most hardware has been powered on. // Be aware that any attempts to access disk, network, the display, etc. may result in // errors or blocking your process until those resources become available. Caller // must NOT acknowledge kIOMessageSystemWillPowerOn; the caller must simply return from its handler. // ----------------------------------------------- // From example code: // ------------------ // System has started the wake up process... // ------------------ break; case IOMessage.KIOMessageSystemHasPoweredOn: // From documentation for IORegisterForSystemPower // ----------------------------------------------- // Delivered at wakeup completion time, after all device drivers and hardware have handled the wakeup event. // Expect this event 1-5 or more seconds after initiating system wakeup. // Caller must NOT acknowledge kIOMessageSystemHasPoweredOn; the caller must simply return from its handler. // ----------------------------------------------- // From example code: // ------------------ // System has finished waking up... // ------------------ serialPortNotifier.OnSystemDidPowerOn(); break; default: break; } }
private void HandleSystemWillSleep(object sender, SystemWillSleepEventArgs args) { DeviceChange.RaiseSystemWillSleepEvent(sender, args); }