Zzz – Rev 1
?pathlinks?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using InTheHand.Net.Bluetooth;
using Newtonsoft.Json.Linq;
using Serilog;
using Zzz.Properties;
namespace Zzz.Idle
{
public class Idler : EventArgs, IDisposable
{
#region Public Properties & Fields
public TimeSpan IdleTimeout {
get {
return _timeout;
}
set {
_timeout = value;
Log.Information("[{Identifier}] Set timeout to {Timeout}.", _identifier, _timeout);
}
}
public bool IsRunning => _running;
#endregion
#region Static Fields and Constants
private Timer _idleTimer;
private MouseInput _mouseInput;
private KeyboardInput _keyboardInput;
private BluetoothScan _bluetoothScan;
private bool _announced;
#endregion
#region Public Events & Delegates
public event EventHandler<IdleEventArgs> Idle;
public event EventHandler<IdleImminentEventArgs> IdleImminent;
#endregion
#region Private Delegates, Events, Enums, Properties, Indexers and Fields
private bool _running;
private WindowPresence _windowPresence;
private TimeSpan _timeout;
private Configuration.Configuration _configuration;
private string _identifier;
#endregion
#region Constructors, Destructors and Finalizers
public Idler(Configuration.Configuration configuration, string identifier)
{
_configuration = configuration;
_identifier = identifier;
}
public void Dispose()
{
if (_windowPresence != null)
{
_windowPresence.WindowDetected -= WindowPresence_WindowDetected;
_windowPresence.Dispose();
_windowPresence = null;
}
if (BluetoothRadio.IsSupported)
{
if (_bluetoothScan != null)
{
_bluetoothScan.BluetoothDeviceDetected -= BluetoothScan_BluetoothDeviceDetected;
_bluetoothScan.Dispose();
_bluetoothScan = null;
}
}
if (_mouseInput != null)
{
_mouseInput.MouseMoved -= MouseInput_MouseMoved;
_mouseInput.MouseClicked -= MouseInput_MouseClicked;
_mouseInput.MouseWheelScrolled -= MouseInput_MouseWheelScrolled;
_mouseInput.Dispose();
_mouseInput = null;
}
if (_keyboardInput != null)
{
_keyboardInput.KeyboardKeyPressed -= KeyboardInput_KeyboardKeyPressed;
_keyboardInput.Dispose();
_keyboardInput = null;
}
}
#endregion
#region Event Handlers
private void BluetoothScan_BluetoothDeviceDetected(object sender, EventArgs e)
{
Log.Information("[{Identifier}] Idler reset by bluetooth device.", _identifier);
_idleTimer?.Change(_timeout, Timeout.InfiniteTimeSpan);
}
private void MouseInput_MouseMoved(object sender, MouseMovedEventArgs e)
{
if (e.Distance < (int)_configuration.MouseMoveTolerance)
{
Log.Information("[{Identifier}] Mouse movement too small to reset idler.", _identifier);
return;
}
Log.Information("[{Identifier}] Idler reset by mouse movement.", _identifier);
_idleTimer?.Change(_timeout, Timeout.InfiniteTimeSpan);
}
private void MouseInput_MouseClicked(object sender, EventArgs e)
{
Log.Information("[{Identifier}] Idler reset by mouse click.", _identifier);
_idleTimer?.Change(_timeout, Timeout.InfiniteTimeSpan);
}
private void MouseInput_MouseWheelScrolled(object sender, EventArgs e)
{
Log.Information("[{Identifier}] Idler reset by mouse scroll.", _identifier);
_idleTimer?.Change(_timeout, Timeout.InfiniteTimeSpan);
}
private void KeyboardInput_KeyboardKeyPressed(object sender, EventArgs e)
{
Log.Information("[{Identifier}] Idler reset by key press.", _identifier);
_idleTimer?.Change(_timeout, Timeout.InfiniteTimeSpan);
}
private void WindowPresence_WindowDetected(object sender, EventArgs e)
{
Log.Information("[{Identifier}] Idler reset by detected window.", _identifier);
_idleTimer?.Change(_timeout, Timeout.InfiniteTimeSpan);
}
#endregion
#region Public Methods
public void Start(TimeSpan timeout)
{
if (_running)
{
return;
}
_timeout = timeout;
// Bind input events.
if (_configuration.MonitorMouse)
{
if (_mouseInput == null)
{
_mouseInput = new MouseInput();
_mouseInput.MouseClicked += MouseInput_MouseClicked;
_mouseInput.MouseMoved += MouseInput_MouseMoved;
_mouseInput.MouseWheelScrolled += MouseInput_MouseWheelScrolled;
}
}
if (_configuration.MonitorKeyboard)
{
if (_keyboardInput == null)
{
_keyboardInput = new KeyboardInput();
_keyboardInput.KeyboardKeyPressed += KeyboardInput_KeyboardKeyPressed;
}
}
// Bind bluetooth events.
if (BluetoothRadio.IsSupported)
{
if (_configuration.MonitorBluetooth)
{
if (_bluetoothScan == null)
{
_bluetoothScan = new BluetoothScan(_configuration);
_bluetoothScan.BluetoothDeviceDetected += BluetoothScan_BluetoothDeviceDetected;
}
}
}
if (_configuration.MonitorWindows)
{
if (_windowPresence == null)
{
_windowPresence = new WindowPresence(_configuration);
_windowPresence.WindowDetected += WindowPresence_WindowDetected;
}
}
// Reset the announcement flag.
_announced = false;
// Reset the idle timer.
_idleTimer = new Timer(IdleTimeCallback, null,
_timeout.Subtract(TimeSpan.FromMinutes(1)),
Timeout.InfiniteTimeSpan);
_running = true;
Log.Information("[{Identifier}] Idler enabled.", _identifier);
}
public void Stop()
{
if (!_running)
{
return;
}
if (_windowPresence != null)
{
_windowPresence.WindowDetected -= WindowPresence_WindowDetected;
_windowPresence.Dispose();
_windowPresence = null;
}
if (BluetoothRadio.IsSupported)
{
if (_bluetoothScan != null)
{
_bluetoothScan.BluetoothDeviceDetected -= BluetoothScan_BluetoothDeviceDetected;
_bluetoothScan.Dispose();
_bluetoothScan = null;
}
}
if (_mouseInput != null)
{
_mouseInput.MouseMoved -= MouseInput_MouseMoved;
_mouseInput.MouseClicked -= MouseInput_MouseClicked;
_mouseInput.MouseWheelScrolled -= MouseInput_MouseWheelScrolled;
_mouseInput.Dispose();
_mouseInput = null;
}
if (_keyboardInput != null)
{
_keyboardInput.KeyboardKeyPressed -= KeyboardInput_KeyboardKeyPressed;
_keyboardInput.Dispose();
_keyboardInput = null;
}
if (_idleTimer != null)
{
_idleTimer.Change(Timeout.Infinite, Timeout.Infinite);
_idleTimer.Dispose();
_idleTimer = null;
}
_running = false;
Log.Information("[{Identifier}] Idler disabled.", _identifier);
}
#endregion
#region Private Methods
private void IdleTimeCallback(object state)
{
if (!_announced)
{
Log.Information("[{Identifier}] Announcing that idle timeout has been reached.", _identifier);
// Invoke the idle imminent event on the parent task scheduler.
IdleImminent?.Invoke(this, new IdleImminentEventArgs());
// Reschedule one minute.
_idleTimer.Change(TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
_announced = true;
return;
}
Log.Information("[{Identifier}] Idling state reached.", _identifier);
// Invoke the idle event on the parent task scheduler.
Idle?.Invoke(this, new IdleEventArgs());
}
#endregion
}
}
Generated by GNU Enscript 1.6.5.90.