SEBWIN-445: Implemented reporting of power supply and wireless adapter status to server.
This commit is contained in:
parent
4d05ef8cad
commit
79a221cf21
3 changed files with 94 additions and 12 deletions
|
@ -37,6 +37,8 @@ using SafeExamBrowser.Settings.UserInterface;
|
||||||
using SafeExamBrowser.SystemComponents;
|
using SafeExamBrowser.SystemComponents;
|
||||||
using SafeExamBrowser.SystemComponents.Audio;
|
using SafeExamBrowser.SystemComponents.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts;
|
using SafeExamBrowser.SystemComponents.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
||||||
using SafeExamBrowser.SystemComponents.Keyboard;
|
using SafeExamBrowser.SystemComponents.Keyboard;
|
||||||
using SafeExamBrowser.SystemComponents.PowerSupply;
|
using SafeExamBrowser.SystemComponents.PowerSupply;
|
||||||
using SafeExamBrowser.SystemComponents.WirelessNetwork;
|
using SafeExamBrowser.SystemComponents.WirelessNetwork;
|
||||||
|
@ -68,12 +70,14 @@ namespace SafeExamBrowser.Client
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IMessageBox messageBox;
|
private IMessageBox messageBox;
|
||||||
private INativeMethods nativeMethods;
|
private INativeMethods nativeMethods;
|
||||||
|
private IPowerSupply powerSupply;
|
||||||
private IRuntimeProxy runtimeProxy;
|
private IRuntimeProxy runtimeProxy;
|
||||||
private ISystemInfo systemInfo;
|
private ISystemInfo systemInfo;
|
||||||
private ITaskbar taskbar;
|
private ITaskbar taskbar;
|
||||||
private ITaskview taskview;
|
private ITaskview taskview;
|
||||||
private IText text;
|
private IText text;
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
private IWirelessAdapter wirelessAdapter;
|
||||||
|
|
||||||
internal ClientController ClientController { get; private set; }
|
internal ClientController ClientController { get; private set; }
|
||||||
|
|
||||||
|
@ -89,10 +93,12 @@ namespace SafeExamBrowser.Client
|
||||||
actionCenter = uiFactory.CreateActionCenter();
|
actionCenter = uiFactory.CreateActionCenter();
|
||||||
messageBox = BuildMessageBox();
|
messageBox = BuildMessageBox();
|
||||||
nativeMethods = new NativeMethods();
|
nativeMethods = new NativeMethods();
|
||||||
|
powerSupply = new PowerSupply(ModuleLogger(nameof(PowerSupply)));
|
||||||
runtimeProxy = new RuntimeProxy(runtimeHostUri, new ProxyObjectFactory(), ModuleLogger(nameof(RuntimeProxy)), Interlocutor.Client);
|
runtimeProxy = new RuntimeProxy(runtimeHostUri, new ProxyObjectFactory(), ModuleLogger(nameof(RuntimeProxy)), Interlocutor.Client);
|
||||||
systemInfo = new SystemInfo();
|
systemInfo = new SystemInfo();
|
||||||
taskbar = uiFactory.CreateTaskbar(ModuleLogger("Taskbar"));
|
taskbar = uiFactory.CreateTaskbar(ModuleLogger("Taskbar"));
|
||||||
taskview = uiFactory.CreateTaskview();
|
taskview = uiFactory.CreateTaskview();
|
||||||
|
wirelessAdapter = new WirelessAdapter(ModuleLogger(nameof(WirelessAdapter)));
|
||||||
|
|
||||||
var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory)));
|
var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory)));
|
||||||
var applicationMonitor = new ApplicationMonitor(TWO_SECONDS, ModuleLogger(nameof(ApplicationMonitor)), nativeMethods, processFactory);
|
var applicationMonitor = new ApplicationMonitor(TWO_SECONDS, ModuleLogger(nameof(ApplicationMonitor)), nativeMethods, processFactory);
|
||||||
|
@ -241,7 +247,7 @@ namespace SafeExamBrowser.Client
|
||||||
|
|
||||||
private IOperation BuildServerOperation()
|
private IOperation BuildServerOperation()
|
||||||
{
|
{
|
||||||
var server = new ServerProxy(context.AppConfig, ModuleLogger(nameof(ServerProxy)));
|
var server = new ServerProxy(context.AppConfig, ModuleLogger(nameof(ServerProxy)), powerSupply, wirelessAdapter);
|
||||||
var operation = new ServerOperation(actionCenter, context, logger, server, taskbar);
|
var operation = new ServerOperation(actionCenter, context, logger, server, taskbar);
|
||||||
|
|
||||||
context.Server = server;
|
context.Server = server;
|
||||||
|
@ -257,8 +263,6 @@ namespace SafeExamBrowser.Client
|
||||||
var keyboard = new Keyboard(ModuleLogger(nameof(Keyboard)));
|
var keyboard = new Keyboard(ModuleLogger(nameof(Keyboard)));
|
||||||
var logInfo = new LogNotificationInfo(text);
|
var logInfo = new LogNotificationInfo(text);
|
||||||
var logController = new LogNotificationController(logger, uiFactory);
|
var logController = new LogNotificationController(logger, uiFactory);
|
||||||
var powerSupply = new PowerSupply(ModuleLogger(nameof(PowerSupply)));
|
|
||||||
var wirelessAdapter = new WirelessAdapter(ModuleLogger(nameof(WirelessAdapter)));
|
|
||||||
var operation = new ShellOperation(
|
var operation = new ShellOperation(
|
||||||
actionCenter,
|
actionCenter,
|
||||||
audio,
|
audio,
|
||||||
|
|
|
@ -79,6 +79,10 @@
|
||||||
<Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project>
|
<Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project>
|
||||||
<Name>SafeExamBrowser.Settings</Name>
|
<Name>SafeExamBrowser.Settings</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\SafeExamBrowser.SystemComponents.Contracts\SafeExamBrowser.SystemComponents.Contracts.csproj">
|
||||||
|
<Project>{903129c6-e236-493b-9ad6-c6a57f647a3a}</Project>
|
||||||
|
<Name>SafeExamBrowser.SystemComponents.Contracts</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
|
|
@ -27,6 +27,8 @@ using SafeExamBrowser.Server.Contracts.Events;
|
||||||
using SafeExamBrowser.Server.Data;
|
using SafeExamBrowser.Server.Data;
|
||||||
using SafeExamBrowser.Settings.Logging;
|
using SafeExamBrowser.Settings.Logging;
|
||||||
using SafeExamBrowser.Settings.Server;
|
using SafeExamBrowser.Settings.Server;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
||||||
using Timer = System.Timers.Timer;
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Server
|
namespace SafeExamBrowser.Server
|
||||||
|
@ -43,21 +45,29 @@ namespace SafeExamBrowser.Server
|
||||||
private ConcurrentQueue<ILogContent> logContent;
|
private ConcurrentQueue<ILogContent> logContent;
|
||||||
private string oauth2Token;
|
private string oauth2Token;
|
||||||
private int pingNumber;
|
private int pingNumber;
|
||||||
|
private IPowerSupply powerSupply;
|
||||||
private ServerSettings settings;
|
private ServerSettings settings;
|
||||||
private Task task;
|
private Task task;
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
|
private IWirelessAdapter wirelessAdapter;
|
||||||
|
|
||||||
public event TerminationRequestedEventHandler TerminationRequested;
|
public event TerminationRequestedEventHandler TerminationRequested;
|
||||||
|
|
||||||
public ServerProxy(AppConfig appConfig, ILogger logger)
|
public ServerProxy(
|
||||||
|
AppConfig appConfig,
|
||||||
|
ILogger logger,
|
||||||
|
IPowerSupply powerSupply = default(IPowerSupply),
|
||||||
|
IWirelessAdapter wirelessAdapter = default(IWirelessAdapter))
|
||||||
{
|
{
|
||||||
this.api = new ApiVersion1();
|
this.api = new ApiVersion1();
|
||||||
this.appConfig = appConfig;
|
this.appConfig = appConfig;
|
||||||
this.cancellationTokenSource = new CancellationTokenSource();
|
this.cancellationTokenSource = new CancellationTokenSource();
|
||||||
this.httpClient = new HttpClient();
|
this.httpClient = new HttpClient();
|
||||||
this.logger = logger;
|
|
||||||
this.logContent = new ConcurrentQueue<ILogContent>();
|
this.logContent = new ConcurrentQueue<ILogContent>();
|
||||||
|
this.logger = logger;
|
||||||
|
this.powerSupply = powerSupply;
|
||||||
this.timer = new Timer();
|
this.timer = new Timer();
|
||||||
|
this.wirelessAdapter = wirelessAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerResponse Connect()
|
public ServerResponse Connect()
|
||||||
|
@ -252,31 +262,40 @@ namespace SafeExamBrowser.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Subscribe(this);
|
logger.Subscribe(this);
|
||||||
|
|
||||||
task = new Task(SendLog, cancellationTokenSource.Token);
|
task = new Task(SendLog, cancellationTokenSource.Token);
|
||||||
task.Start();
|
task.Start();
|
||||||
|
|
||||||
logger.Info("Started sending log items.");
|
logger.Info("Started sending log items.");
|
||||||
|
|
||||||
timer.AutoReset = false;
|
timer.AutoReset = false;
|
||||||
timer.Elapsed += Timer_Elapsed;
|
timer.Elapsed += Timer_Elapsed;
|
||||||
timer.Interval = 1000;
|
timer.Interval = 1000;
|
||||||
timer.Start();
|
timer.Start();
|
||||||
|
|
||||||
logger.Info("Starting sending pings.");
|
logger.Info("Starting sending pings.");
|
||||||
|
|
||||||
|
if (powerSupply != default(IPowerSupply) && wirelessAdapter != default(IWirelessAdapter))
|
||||||
|
{
|
||||||
|
powerSupply.StatusChanged += PowerSupply_StatusChanged;
|
||||||
|
wirelessAdapter.NetworksChanged += WirelessAdapter_NetworksChanged;
|
||||||
|
logger.Info("Started monitoring system components.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopConnectivity()
|
public void StopConnectivity()
|
||||||
{
|
{
|
||||||
|
if (powerSupply != default(IPowerSupply) && wirelessAdapter != default(IWirelessAdapter))
|
||||||
|
{
|
||||||
|
powerSupply.StatusChanged -= PowerSupply_StatusChanged;
|
||||||
|
wirelessAdapter.NetworksChanged -= WirelessAdapter_NetworksChanged;
|
||||||
|
logger.Info("Stopped monitoring system components.");
|
||||||
|
}
|
||||||
|
|
||||||
logger.Unsubscribe(this);
|
logger.Unsubscribe(this);
|
||||||
cancellationTokenSource.Cancel();
|
cancellationTokenSource.Cancel();
|
||||||
task?.Wait();
|
task?.Wait();
|
||||||
|
|
||||||
logger.Info("Stopped sending log items.");
|
logger.Info("Stopped sending log items.");
|
||||||
|
|
||||||
timer.Stop();
|
timer.Stop();
|
||||||
timer.Elapsed -= Timer_Elapsed;
|
timer.Elapsed -= Timer_Elapsed;
|
||||||
|
|
||||||
logger.Info("Stopped sending pings.");
|
logger.Info("Stopped sending pings.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,7 +318,8 @@ namespace SafeExamBrowser.Server
|
||||||
["text"] = message.Message
|
["text"] = message.Message
|
||||||
};
|
};
|
||||||
var content = json.ToString();
|
var content = json.ToString();
|
||||||
var success = TryExecute(HttpMethod.Post, api.LogEndpoint, out var response, content, contentType, authorization, token);
|
|
||||||
|
TryExecute(HttpMethod.Post, api.LogEndpoint, out var response, content, contentType, authorization, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -309,6 +329,32 @@ namespace SafeExamBrowser.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PowerSupply_StatusChanged(IPowerSupplyStatus status)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var authorization = ("Authorization", $"Bearer {oauth2Token}");
|
||||||
|
var chargeInfo = $"{status.BatteryChargeStatus} at {Convert.ToInt32(status.BatteryCharge * 100)}%";
|
||||||
|
var contentType = "application/json;charset=UTF-8";
|
||||||
|
var gridInfo = $"{(status.IsOnline ? "connected to" : "disconnected from")} the power grid";
|
||||||
|
var token = ("SEBConnectionToken", connectionToken);
|
||||||
|
var json = new JObject
|
||||||
|
{
|
||||||
|
["type"] = ToLogType(LogLevel.Info),
|
||||||
|
["timestamp"] = ToUnixTimestamp(DateTime.Now),
|
||||||
|
["text"] = $"<battery> {chargeInfo}, {status.BatteryTimeRemaining} remaining, {gridInfo}",
|
||||||
|
["numericValue"] = Convert.ToInt32(status.BatteryCharge * 100)
|
||||||
|
};
|
||||||
|
var content = json.ToString();
|
||||||
|
|
||||||
|
TryExecute(HttpMethod.Post, api.LogEndpoint, out var response, content, contentType, authorization, token);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error("Failed to send power supply status!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Timer_Elapsed(object sender, ElapsedEventArgs args)
|
private void Timer_Elapsed(object sender, ElapsedEventArgs args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -344,6 +390,34 @@ namespace SafeExamBrowser.Server
|
||||||
timer.Start();
|
timer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void WirelessAdapter_NetworksChanged()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var authorization = ("Authorization", $"Bearer {oauth2Token}");
|
||||||
|
var contentType = "application/json;charset=UTF-8";
|
||||||
|
var network = wirelessAdapter.GetNetworks().FirstOrDefault(n => n.Status == WirelessNetworkStatus.Connected);
|
||||||
|
var token = ("SEBConnectionToken", connectionToken);
|
||||||
|
var json = new JObject { ["type"] = ToLogType(LogLevel.Info), ["timestamp"] = ToUnixTimestamp(DateTime.Now) };
|
||||||
|
|
||||||
|
if (network != default(IWirelessNetwork))
|
||||||
|
{
|
||||||
|
json["text"] = $"<wlan> {network.Name}: {network.Status}, {network.SignalStrength}%";
|
||||||
|
json["numericValue"] = network.SignalStrength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
json["text"] = "<wlan> not connected";
|
||||||
|
}
|
||||||
|
|
||||||
|
TryExecute(HttpMethod.Post, api.LogEndpoint, out var response, json.ToString(), contentType, authorization, token);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error("Failed to send wireless status!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool TryParseApi(HttpContent content)
|
private bool TryParseApi(HttpContent content)
|
||||||
{
|
{
|
||||||
var success = false;
|
var success = false;
|
||||||
|
@ -384,7 +458,7 @@ namespace SafeExamBrowser.Server
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
logger.Error("The selected SEB server instance does not support the required API version!");
|
logger.Error("The selected SEB server instance does not support the required API version!");
|
||||||
|
|
Loading…
Reference in a new issue