SEBWIN-537: Implemented new network control showing wired as well as wireless network information.
This commit is contained in:
parent
3dda11956e
commit
6205bef251
57 changed files with 997 additions and 949 deletions
|
@ -18,8 +18,8 @@ using SafeExamBrowser.Settings.Applications;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts;
|
using SafeExamBrowser.SystemComponents.Contracts;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
private Mock<ITaskview> taskview;
|
private Mock<ITaskview> taskview;
|
||||||
private Mock<IText> text;
|
private Mock<IText> text;
|
||||||
private Mock<IUserInterfaceFactory> uiFactory;
|
private Mock<IUserInterfaceFactory> uiFactory;
|
||||||
private Mock<IWirelessAdapter> wirelessAdapter;
|
private Mock<INetworkAdapter> networkAdapter;
|
||||||
|
|
||||||
private ShellOperation sut;
|
private ShellOperation sut;
|
||||||
|
|
||||||
|
@ -55,13 +55,13 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
aboutNotification = new Mock<INotification>();
|
aboutNotification = new Mock<INotification>();
|
||||||
keyboard = new Mock<IKeyboard>();
|
keyboard = new Mock<IKeyboard>();
|
||||||
logNotification = new Mock<INotification>();
|
logNotification = new Mock<INotification>();
|
||||||
|
networkAdapter = new Mock<INetworkAdapter>();
|
||||||
powerSupply = new Mock<IPowerSupply>();
|
powerSupply = new Mock<IPowerSupply>();
|
||||||
systemInfo = new Mock<ISystemInfo>();
|
systemInfo = new Mock<ISystemInfo>();
|
||||||
taskbar = new Mock<ITaskbar>();
|
taskbar = new Mock<ITaskbar>();
|
||||||
taskview = new Mock<ITaskview>();
|
taskview = new Mock<ITaskview>();
|
||||||
text = new Mock<IText>();
|
text = new Mock<IText>();
|
||||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||||
wirelessAdapter = new Mock<IWirelessAdapter>();
|
|
||||||
|
|
||||||
context.Settings = new AppSettings();
|
context.Settings = new AppSettings();
|
||||||
|
|
||||||
|
@ -77,13 +77,13 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
keyboard.Object,
|
keyboard.Object,
|
||||||
logger.Object,
|
logger.Object,
|
||||||
logNotification.Object,
|
logNotification.Object,
|
||||||
|
networkAdapter.Object,
|
||||||
powerSupply.Object,
|
powerSupply.Object,
|
||||||
systemInfo.Object,
|
systemInfo.Object,
|
||||||
taskbar.Object,
|
taskbar.Object,
|
||||||
taskview.Object,
|
taskview.Object,
|
||||||
text.Object,
|
text.Object,
|
||||||
uiFactory.Object,
|
uiFactory.Object);
|
||||||
wirelessAdapter.Object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -99,7 +99,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
context.Settings.ActionCenter.EnableActionCenter = true;
|
context.Settings.ActionCenter.EnableActionCenter = true;
|
||||||
context.Settings.Keyboard.AllowAltTab = true;
|
context.Settings.Keyboard.AllowAltTab = true;
|
||||||
context.Settings.Security.AllowTermination = true;
|
context.Settings.Security.AllowTermination = true;
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
actionCenter.Verify(a => a.Register(It.Is<IActionCenterActivator>(a2 => a2 == actionCenterActivator.Object)), Times.Once);
|
actionCenter.Verify(a => a.Register(It.Is<IActionCenterActivator>(a2 => a2 == actionCenterActivator.Object)), Times.Once);
|
||||||
|
@ -281,23 +281,23 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
context.Settings.ActionCenter.EnableActionCenter = true;
|
context.Settings.ActionCenter.EnableActionCenter = true;
|
||||||
context.Settings.ActionCenter.ShowAudio = true;
|
context.Settings.ActionCenter.ShowAudio = true;
|
||||||
context.Settings.ActionCenter.ShowKeyboardLayout = true;
|
context.Settings.ActionCenter.ShowKeyboardLayout = true;
|
||||||
context.Settings.ActionCenter.ShowWirelessNetwork = true;
|
context.Settings.ActionCenter.ShowNetwork = true;
|
||||||
context.Settings.Taskbar.EnableTaskbar = true;
|
context.Settings.Taskbar.EnableTaskbar = true;
|
||||||
context.Settings.Taskbar.ShowAudio = true;
|
context.Settings.Taskbar.ShowAudio = true;
|
||||||
context.Settings.Taskbar.ShowKeyboardLayout = true;
|
context.Settings.Taskbar.ShowKeyboardLayout = true;
|
||||||
context.Settings.Taskbar.ShowWirelessNetwork = true;
|
context.Settings.Taskbar.ShowNetwork = true;
|
||||||
|
|
||||||
systemInfo.SetupGet(s => s.HasBattery).Returns(true);
|
systemInfo.SetupGet(s => s.HasBattery).Returns(true);
|
||||||
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<IAudio>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<IAudio>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<IPowerSupply>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<IPowerSupply>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreateWirelessNetworkControl(It.IsAny<IWirelessAdapter>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreateNetworkControl(It.IsAny<INetworkAdapter>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
audio.Verify(a => a.Initialize(), Times.Once);
|
audio.Verify(a => a.Initialize(), Times.Once);
|
||||||
powerSupply.Verify(p => p.Initialize(), Times.Once);
|
powerSupply.Verify(p => p.Initialize(), Times.Once);
|
||||||
wirelessAdapter.Verify(w => w.Initialize(), Times.Once);
|
networkAdapter.Verify(w => w.Initialize(), Times.Once);
|
||||||
keyboard.Verify(k => k.Initialize(), Times.Once);
|
keyboard.Verify(k => k.Initialize(), Times.Once);
|
||||||
actionCenter.Verify(a => a.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(4));
|
actionCenter.Verify(a => a.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(4));
|
||||||
taskbar.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(4));
|
taskbar.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(4));
|
||||||
|
@ -309,23 +309,23 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
context.Settings.ActionCenter.EnableActionCenter = true;
|
context.Settings.ActionCenter.EnableActionCenter = true;
|
||||||
context.Settings.ActionCenter.ShowAudio = false;
|
context.Settings.ActionCenter.ShowAudio = false;
|
||||||
context.Settings.ActionCenter.ShowKeyboardLayout = false;
|
context.Settings.ActionCenter.ShowKeyboardLayout = false;
|
||||||
context.Settings.ActionCenter.ShowWirelessNetwork = false;
|
context.Settings.ActionCenter.ShowNetwork = false;
|
||||||
context.Settings.Taskbar.EnableTaskbar = true;
|
context.Settings.Taskbar.EnableTaskbar = true;
|
||||||
context.Settings.Taskbar.ShowAudio = false;
|
context.Settings.Taskbar.ShowAudio = false;
|
||||||
context.Settings.Taskbar.ShowKeyboardLayout = false;
|
context.Settings.Taskbar.ShowKeyboardLayout = false;
|
||||||
context.Settings.Taskbar.ShowWirelessNetwork = false;
|
context.Settings.Taskbar.ShowNetwork = false;
|
||||||
|
|
||||||
systemInfo.SetupGet(s => s.HasBattery).Returns(false);
|
systemInfo.SetupGet(s => s.HasBattery).Returns(false);
|
||||||
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<IAudio>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreateAudioControl(It.IsAny<IAudio>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreateKeyboardLayoutControl(It.IsAny<IKeyboard>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<IPowerSupply>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreatePowerSupplyControl(It.IsAny<IPowerSupply>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
uiFactory.Setup(f => f.CreateWirelessNetworkControl(It.IsAny<IWirelessAdapter>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
uiFactory.Setup(f => f.CreateNetworkControl(It.IsAny<INetworkAdapter>(), It.IsAny<Location>())).Returns(new Mock<ISystemControl>().Object);
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
audio.Verify(a => a.Initialize(), Times.Once);
|
audio.Verify(a => a.Initialize(), Times.Once);
|
||||||
powerSupply.Verify(p => p.Initialize(), Times.Once);
|
powerSupply.Verify(p => p.Initialize(), Times.Once);
|
||||||
wirelessAdapter.Verify(w => w.Initialize(), Times.Once);
|
networkAdapter.Verify(w => w.Initialize(), Times.Once);
|
||||||
keyboard.Verify(k => k.Initialize(), Times.Once);
|
keyboard.Verify(k => k.Initialize(), Times.Once);
|
||||||
actionCenter.Verify(a => a.AddSystemControl(It.IsAny<ISystemControl>()), Times.Never);
|
actionCenter.Verify(a => a.AddSystemControl(It.IsAny<ISystemControl>()), Times.Never);
|
||||||
taskbar.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Never);
|
taskbar.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Never);
|
||||||
|
@ -408,7 +408,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
logNotification.Verify(c => c.Terminate(), Times.Once);
|
logNotification.Verify(c => c.Terminate(), Times.Once);
|
||||||
powerSupply.Verify(p => p.Terminate(), Times.Once);
|
powerSupply.Verify(p => p.Terminate(), Times.Once);
|
||||||
keyboard.Verify(k => k.Terminate(), Times.Once);
|
keyboard.Verify(k => k.Terminate(), Times.Once);
|
||||||
wirelessAdapter.Verify(w => w.Terminate(), Times.Once);
|
networkAdapter.Verify(w => w.Terminate(), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,11 +38,11 @@ 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.Network;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.SystemComponents.Keyboard;
|
using SafeExamBrowser.SystemComponents.Keyboard;
|
||||||
|
using SafeExamBrowser.SystemComponents.Network;
|
||||||
using SafeExamBrowser.SystemComponents.PowerSupply;
|
using SafeExamBrowser.SystemComponents.PowerSupply;
|
||||||
using SafeExamBrowser.SystemComponents.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.FileSystemDialog;
|
using SafeExamBrowser.UserInterface.Contracts.FileSystemDialog;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||||
|
@ -71,6 +71,7 @@ namespace SafeExamBrowser.Client
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IMessageBox messageBox;
|
private IMessageBox messageBox;
|
||||||
private INativeMethods nativeMethods;
|
private INativeMethods nativeMethods;
|
||||||
|
private INetworkAdapter networkAdapter;
|
||||||
private IPowerSupply powerSupply;
|
private IPowerSupply powerSupply;
|
||||||
private IRuntimeProxy runtimeProxy;
|
private IRuntimeProxy runtimeProxy;
|
||||||
private ISystemInfo systemInfo;
|
private ISystemInfo systemInfo;
|
||||||
|
@ -79,7 +80,6 @@ namespace SafeExamBrowser.Client
|
||||||
private IUserInfo userInfo;
|
private IUserInfo userInfo;
|
||||||
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; }
|
||||||
|
|
||||||
|
@ -96,13 +96,13 @@ namespace SafeExamBrowser.Client
|
||||||
context = new ClientContext();
|
context = new ClientContext();
|
||||||
messageBox = BuildMessageBox();
|
messageBox = BuildMessageBox();
|
||||||
nativeMethods = new NativeMethods();
|
nativeMethods = new NativeMethods();
|
||||||
|
networkAdapter = new NetworkAdapter(ModuleLogger(nameof(NetworkAdapter)), nativeMethods);
|
||||||
powerSupply = new PowerSupply(ModuleLogger(nameof(PowerSupply)));
|
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();
|
||||||
userInfo = new UserInfo(ModuleLogger(nameof(UserInfo)));
|
userInfo = new UserInfo(ModuleLogger(nameof(UserInfo)));
|
||||||
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);
|
||||||
|
@ -157,13 +157,13 @@ namespace SafeExamBrowser.Client
|
||||||
|
|
||||||
internal void LogStartupInformation()
|
internal void LogStartupInformation()
|
||||||
{
|
{
|
||||||
logger.Log($"# New client instance started at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
|
logger.Log($"# New client instance started at {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
|
||||||
logger.Log(string.Empty);
|
logger.Log(string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void LogShutdownInformation()
|
internal void LogShutdownInformation()
|
||||||
{
|
{
|
||||||
logger?.Log($"# Client instance terminated at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
|
logger?.Log($"# Client instance terminated at {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ValidateCommandLineArguments()
|
private void ValidateCommandLineArguments()
|
||||||
|
@ -271,7 +271,7 @@ namespace SafeExamBrowser.Client
|
||||||
|
|
||||||
private IOperation BuildServerOperation()
|
private IOperation BuildServerOperation()
|
||||||
{
|
{
|
||||||
var server = new ServerProxy(context.AppConfig, ModuleLogger(nameof(ServerProxy)), systemInfo, userInfo, powerSupply, wirelessAdapter);
|
var server = new ServerProxy(context.AppConfig, ModuleLogger(nameof(ServerProxy)), systemInfo, userInfo, powerSupply, networkAdapter);
|
||||||
var operation = new ServerOperation(context, logger, server);
|
var operation = new ServerOperation(context, logger, server);
|
||||||
|
|
||||||
context.Server = server;
|
context.Server = server;
|
||||||
|
@ -293,13 +293,13 @@ namespace SafeExamBrowser.Client
|
||||||
keyboard,
|
keyboard,
|
||||||
logger,
|
logger,
|
||||||
logNotification,
|
logNotification,
|
||||||
|
networkAdapter,
|
||||||
powerSupply,
|
powerSupply,
|
||||||
systemInfo,
|
systemInfo,
|
||||||
taskbar,
|
taskbar,
|
||||||
taskview,
|
taskview,
|
||||||
text,
|
text,
|
||||||
uiFactory,
|
uiFactory);
|
||||||
wirelessAdapter);
|
|
||||||
|
|
||||||
context.Activators.Add(new ActionCenterKeyboardActivator(ModuleLogger(nameof(ActionCenterKeyboardActivator)), nativeMethods));
|
context.Activators.Add(new ActionCenterKeyboardActivator(ModuleLogger(nameof(ActionCenterKeyboardActivator)), nativeMethods));
|
||||||
context.Activators.Add(new ActionCenterTouchActivator(ModuleLogger(nameof(ActionCenterTouchActivator)), nativeMethods));
|
context.Activators.Add(new ActionCenterTouchActivator(ModuleLogger(nameof(ActionCenterTouchActivator)), nativeMethods));
|
||||||
|
|
|
@ -15,8 +15,8 @@ using SafeExamBrowser.Logging.Contracts;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts;
|
using SafeExamBrowser.SystemComponents.Contracts;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
|
|
||||||
|
@ -24,19 +24,19 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
{
|
{
|
||||||
internal class ShellOperation : ClientOperation
|
internal class ShellOperation : ClientOperation
|
||||||
{
|
{
|
||||||
private IActionCenter actionCenter;
|
private readonly IActionCenter actionCenter;
|
||||||
private IAudio audio;
|
private readonly IAudio audio;
|
||||||
private INotification aboutNotification;
|
private readonly INotification aboutNotification;
|
||||||
private IKeyboard keyboard;
|
private readonly IKeyboard keyboard;
|
||||||
private ILogger logger;
|
private readonly ILogger logger;
|
||||||
private INotification logNotification;
|
private readonly INotification logNotification;
|
||||||
private IPowerSupply powerSupply;
|
private readonly INetworkAdapter networkAdapter;
|
||||||
private ISystemInfo systemInfo;
|
private readonly IPowerSupply powerSupply;
|
||||||
private ITaskbar taskbar;
|
private readonly ISystemInfo systemInfo;
|
||||||
private ITaskview taskview;
|
private readonly ITaskbar taskbar;
|
||||||
private IText text;
|
private readonly ITaskview taskview;
|
||||||
private IUserInterfaceFactory uiFactory;
|
private readonly IText text;
|
||||||
private IWirelessAdapter wirelessAdapter;
|
private readonly IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||||
public override event StatusChangedEventHandler StatusChanged;
|
public override event StatusChangedEventHandler StatusChanged;
|
||||||
|
@ -49,13 +49,13 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
IKeyboard keyboard,
|
IKeyboard keyboard,
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
INotification logNotification,
|
INotification logNotification,
|
||||||
|
INetworkAdapter networkAdapter,
|
||||||
IPowerSupply powerSupply,
|
IPowerSupply powerSupply,
|
||||||
ISystemInfo systemInfo,
|
ISystemInfo systemInfo,
|
||||||
ITaskbar taskbar,
|
ITaskbar taskbar,
|
||||||
ITaskview taskview,
|
ITaskview taskview,
|
||||||
IText text,
|
IText text,
|
||||||
IUserInterfaceFactory uiFactory,
|
IUserInterfaceFactory uiFactory) : base(context)
|
||||||
IWirelessAdapter wirelessAdapter) : base(context)
|
|
||||||
{
|
{
|
||||||
this.aboutNotification = aboutNotification;
|
this.aboutNotification = aboutNotification;
|
||||||
this.actionCenter = actionCenter;
|
this.actionCenter = actionCenter;
|
||||||
|
@ -63,13 +63,13 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
this.keyboard = keyboard;
|
this.keyboard = keyboard;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.logNotification = logNotification;
|
this.logNotification = logNotification;
|
||||||
|
this.networkAdapter = networkAdapter;
|
||||||
this.powerSupply = powerSupply;
|
this.powerSupply = powerSupply;
|
||||||
this.systemInfo = systemInfo;
|
this.systemInfo = systemInfo;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.taskbar = taskbar;
|
this.taskbar = taskbar;
|
||||||
this.taskview = taskview;
|
this.taskview = taskview;
|
||||||
this.uiFactory = uiFactory;
|
this.uiFactory = uiFactory;
|
||||||
this.wirelessAdapter = wirelessAdapter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override OperationResult Perform()
|
public override OperationResult Perform()
|
||||||
|
@ -134,7 +134,7 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
InitializeClockForActionCenter();
|
InitializeClockForActionCenter();
|
||||||
InitializeLogNotificationForActionCenter();
|
InitializeLogNotificationForActionCenter();
|
||||||
InitializeKeyboardLayoutForActionCenter();
|
InitializeKeyboardLayoutForActionCenter();
|
||||||
InitializeWirelessNetworkForActionCenter();
|
InitializeNetworkForActionCenter();
|
||||||
InitializePowerSupplyForActionCenter();
|
InitializePowerSupplyForActionCenter();
|
||||||
InitializeQuitButtonForActionCenter();
|
InitializeQuitButtonForActionCenter();
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
InitializeAboutNotificationForTaskbar();
|
InitializeAboutNotificationForTaskbar();
|
||||||
InitializeLogNotificationForTaskbar();
|
InitializeLogNotificationForTaskbar();
|
||||||
InitializePowerSupplyForTaskbar();
|
InitializePowerSupplyForTaskbar();
|
||||||
InitializeWirelessNetworkForTaskbar();
|
InitializeNetworkForTaskbar();
|
||||||
InitializeAudioForTaskbar();
|
InitializeAudioForTaskbar();
|
||||||
InitializeKeyboardLayoutForTaskbar();
|
InitializeKeyboardLayoutForTaskbar();
|
||||||
InitializeClockForTaskbar();
|
InitializeClockForTaskbar();
|
||||||
|
@ -204,8 +204,8 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
{
|
{
|
||||||
audio.Initialize();
|
audio.Initialize();
|
||||||
keyboard.Initialize();
|
keyboard.Initialize();
|
||||||
|
networkAdapter.Initialize();
|
||||||
powerSupply.Initialize();
|
powerSupply.Initialize();
|
||||||
wirelessAdapter.Initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeAboutNotificationForActionCenter()
|
private void InitializeAboutNotificationForActionCenter()
|
||||||
|
@ -308,19 +308,19 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
taskbar.ShowQuitButton = Context.Settings.Security.AllowTermination;
|
taskbar.ShowQuitButton = Context.Settings.Security.AllowTermination;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeWirelessNetworkForActionCenter()
|
private void InitializeNetworkForActionCenter()
|
||||||
{
|
{
|
||||||
if (Context.Settings.ActionCenter.ShowWirelessNetwork)
|
if (Context.Settings.ActionCenter.ShowNetwork)
|
||||||
{
|
{
|
||||||
actionCenter.AddSystemControl(uiFactory.CreateWirelessNetworkControl(wirelessAdapter, Location.ActionCenter));
|
actionCenter.AddSystemControl(uiFactory.CreateNetworkControl(networkAdapter, Location.ActionCenter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeWirelessNetworkForTaskbar()
|
private void InitializeNetworkForTaskbar()
|
||||||
{
|
{
|
||||||
if (Context.Settings.Taskbar.ShowWirelessNetwork)
|
if (Context.Settings.Taskbar.ShowNetwork)
|
||||||
{
|
{
|
||||||
taskbar.AddSystemControl(uiFactory.CreateWirelessNetworkControl(wirelessAdapter, Location.Taskbar));
|
taskbar.AddSystemControl(uiFactory.CreateNetworkControl(networkAdapter, Location.Taskbar));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,8 +342,8 @@ namespace SafeExamBrowser.Client.Operations
|
||||||
{
|
{
|
||||||
audio.Terminate();
|
audio.Terminate();
|
||||||
keyboard.Terminate();
|
keyboard.Terminate();
|
||||||
|
networkAdapter.Terminate();
|
||||||
powerSupply.Terminate();
|
powerSupply.Terminate();
|
||||||
wirelessAdapter.Terminate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ namespace SafeExamBrowser.Configuration.UnitTests
|
||||||
private Mock<ICertificateStore> certificateStore;
|
private Mock<ICertificateStore> certificateStore;
|
||||||
private Mock<IResourceLoader> fileLoader;
|
private Mock<IResourceLoader> fileLoader;
|
||||||
private Mock<IResourceSaver> fileSaver;
|
private Mock<IResourceSaver> fileSaver;
|
||||||
private Mock<IHashAlgorithm> hashAlgorithm;
|
|
||||||
private Mock<IModuleLogger> logger;
|
private Mock<IModuleLogger> logger;
|
||||||
private Mock<IResourceLoader> networkLoader;
|
private Mock<IResourceLoader> networkLoader;
|
||||||
private Mock<IDataParser> xmlParser;
|
private Mock<IDataParser> xmlParser;
|
||||||
|
@ -44,7 +43,6 @@ namespace SafeExamBrowser.Configuration.UnitTests
|
||||||
certificateStore = new Mock<ICertificateStore>();
|
certificateStore = new Mock<ICertificateStore>();
|
||||||
fileLoader = new Mock<IResourceLoader>();
|
fileLoader = new Mock<IResourceLoader>();
|
||||||
fileSaver = new Mock<IResourceSaver>();
|
fileSaver = new Mock<IResourceSaver>();
|
||||||
hashAlgorithm = new Mock<IHashAlgorithm>();
|
|
||||||
logger = new Mock<IModuleLogger>();
|
logger = new Mock<IModuleLogger>();
|
||||||
networkLoader = new Mock<IResourceLoader>();
|
networkLoader = new Mock<IResourceLoader>();
|
||||||
xmlParser = new Mock<IDataParser>();
|
xmlParser = new Mock<IDataParser>();
|
||||||
|
@ -56,7 +54,7 @@ namespace SafeExamBrowser.Configuration.UnitTests
|
||||||
|
|
||||||
SetEntryAssembly();
|
SetEntryAssembly();
|
||||||
|
|
||||||
sut = new ConfigurationRepository(certificateStore.Object, hashAlgorithm.Object, logger.Object);
|
sut = new ConfigurationRepository(certificateStore.Object, logger.Object);
|
||||||
sut.InitializeAppConfig();
|
sut.InitializeAppConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,8 @@ namespace SafeExamBrowser.Configuration.ConfigurationData.DataMapping
|
||||||
case Keys.UserInterface.ShowKeyboardLayout:
|
case Keys.UserInterface.ShowKeyboardLayout:
|
||||||
MapShowKeyboardLayout(settings, value);
|
MapShowKeyboardLayout(settings, value);
|
||||||
break;
|
break;
|
||||||
case Keys.UserInterface.ShowWirelessNetwork:
|
case Keys.UserInterface.ShowNetwork:
|
||||||
MapShowWirelessNetwork(settings, value);
|
MapShowNetwork(settings, value);
|
||||||
break;
|
break;
|
||||||
case Keys.UserInterface.Taskbar.EnableTaskbar:
|
case Keys.UserInterface.Taskbar.EnableTaskbar:
|
||||||
MapEnableTaskbar(settings, value);
|
MapEnableTaskbar(settings, value);
|
||||||
|
@ -79,12 +79,12 @@ namespace SafeExamBrowser.Configuration.ConfigurationData.DataMapping
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MapShowWirelessNetwork(AppSettings settings, object value)
|
private void MapShowNetwork(AppSettings settings, object value)
|
||||||
{
|
{
|
||||||
if (value is bool show)
|
if (value is bool show)
|
||||||
{
|
{
|
||||||
settings.ActionCenter.ShowWirelessNetwork = show;
|
settings.ActionCenter.ShowNetwork = show;
|
||||||
settings.Taskbar.ShowWirelessNetwork = show;
|
settings.Taskbar.ShowNetwork = show;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,9 +101,9 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
||||||
settings.ActionCenter.EnableActionCenter = true;
|
settings.ActionCenter.EnableActionCenter = true;
|
||||||
settings.ActionCenter.ShowApplicationInfo = true;
|
settings.ActionCenter.ShowApplicationInfo = true;
|
||||||
settings.ActionCenter.ShowApplicationLog = false;
|
settings.ActionCenter.ShowApplicationLog = false;
|
||||||
settings.ActionCenter.ShowKeyboardLayout = true;
|
|
||||||
settings.ActionCenter.ShowWirelessNetwork = false;
|
|
||||||
settings.ActionCenter.ShowClock = true;
|
settings.ActionCenter.ShowClock = true;
|
||||||
|
settings.ActionCenter.ShowKeyboardLayout = true;
|
||||||
|
settings.ActionCenter.ShowNetwork = false;
|
||||||
|
|
||||||
settings.Applications.Blacklist.Add(new BlacklistApplication { ExecutableName = "AA_v3.exe", OriginalName = "AA_v3.exe" });
|
settings.Applications.Blacklist.Add(new BlacklistApplication { ExecutableName = "AA_v3.exe", OriginalName = "AA_v3.exe" });
|
||||||
settings.Applications.Blacklist.Add(new BlacklistApplication { ExecutableName = "AeroAdmin.exe", OriginalName = "AeroAdmin.exe" });
|
settings.Applications.Blacklist.Add(new BlacklistApplication { ExecutableName = "AeroAdmin.exe", OriginalName = "AeroAdmin.exe" });
|
||||||
|
@ -283,12 +283,12 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
||||||
settings.Taskbar.EnableTaskbar = true;
|
settings.Taskbar.EnableTaskbar = true;
|
||||||
settings.Taskbar.ShowApplicationInfo = false;
|
settings.Taskbar.ShowApplicationInfo = false;
|
||||||
settings.Taskbar.ShowApplicationLog = false;
|
settings.Taskbar.ShowApplicationLog = false;
|
||||||
settings.Taskbar.ShowKeyboardLayout = true;
|
|
||||||
settings.Taskbar.ShowWirelessNetwork = false;
|
|
||||||
settings.Taskbar.ShowClock = true;
|
settings.Taskbar.ShowClock = true;
|
||||||
|
settings.Taskbar.ShowKeyboardLayout = true;
|
||||||
|
settings.Taskbar.ShowNetwork = false;
|
||||||
|
|
||||||
settings.UserInterfaceMode = UserInterfaceMode.Desktop;
|
settings.UserInterfaceMode = UserInterfaceMode.Desktop;
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,7 +327,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
||||||
internal const string ShowAudio = "audioControlEnabled";
|
internal const string ShowAudio = "audioControlEnabled";
|
||||||
internal const string ShowClock = "showTime";
|
internal const string ShowClock = "showTime";
|
||||||
internal const string ShowKeyboardLayout = "showInputLanguage";
|
internal const string ShowKeyboardLayout = "showInputLanguage";
|
||||||
internal const string ShowWirelessNetwork = "allowWlan";
|
internal const string ShowNetwork = "allowWlan";
|
||||||
internal const string UserInterfaceMode = "touchOptimized";
|
internal const string UserInterfaceMode = "touchOptimized";
|
||||||
|
|
||||||
internal static class ActionCenter
|
internal static class ActionCenter
|
||||||
|
|
|
@ -22,21 +22,19 @@ namespace SafeExamBrowser.Configuration
|
||||||
{
|
{
|
||||||
public class ConfigurationRepository : IConfigurationRepository
|
public class ConfigurationRepository : IConfigurationRepository
|
||||||
{
|
{
|
||||||
private ICertificateStore certificateStore;
|
private readonly ICertificateStore certificateStore;
|
||||||
private IList<IDataParser> dataParsers;
|
private readonly IList<IDataParser> dataParsers;
|
||||||
private IList<IDataSerializer> dataSerializers;
|
private readonly IList<IDataSerializer> dataSerializers;
|
||||||
private DataMapper dataMapper;
|
private readonly DataMapper dataMapper;
|
||||||
private DataProcessor dataProcessor;
|
private readonly DataProcessor dataProcessor;
|
||||||
private DataValues dataValues;
|
private readonly DataValues dataValues;
|
||||||
private IHashAlgorithm hashAlgorithm;
|
private readonly ILogger logger;
|
||||||
private ILogger logger;
|
private readonly IList<IResourceLoader> resourceLoaders;
|
||||||
private IList<IResourceLoader> resourceLoaders;
|
private readonly IList<IResourceSaver> resourceSavers;
|
||||||
private IList<IResourceSaver> resourceSavers;
|
|
||||||
|
|
||||||
public ConfigurationRepository(ICertificateStore certificateStore, IHashAlgorithm hashAlgorithm, IModuleLogger logger)
|
public ConfigurationRepository(ICertificateStore certificateStore, IModuleLogger logger)
|
||||||
{
|
{
|
||||||
this.certificateStore = certificateStore;
|
this.certificateStore = certificateStore;
|
||||||
this.hashAlgorithm = hashAlgorithm;
|
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
|
||||||
dataParsers = new List<IDataParser>();
|
dataParsers = new List<IDataParser>();
|
||||||
|
@ -171,7 +169,7 @@ namespace SafeExamBrowser.Configuration
|
||||||
var status = LoadStatus.NotSupported;
|
var status = LoadStatus.NotSupported;
|
||||||
var resourceLoader = resourceLoaders.FirstOrDefault(l => l.CanLoad(resource));
|
var resourceLoader = resourceLoaders.FirstOrDefault(l => l.CanLoad(resource));
|
||||||
|
|
||||||
data = default(Stream);
|
data = default;
|
||||||
|
|
||||||
if (resourceLoader != null)
|
if (resourceLoader != null)
|
||||||
{
|
{
|
||||||
|
@ -191,8 +189,8 @@ namespace SafeExamBrowser.Configuration
|
||||||
var parser = dataParsers.FirstOrDefault(p => p.CanParse(data));
|
var parser = dataParsers.FirstOrDefault(p => p.CanParse(data));
|
||||||
var status = LoadStatus.NotSupported;
|
var status = LoadStatus.NotSupported;
|
||||||
|
|
||||||
encryption = default(EncryptionParameters);
|
encryption = default;
|
||||||
format = default(FormatType);
|
format = default;
|
||||||
rawData = default(Dictionary<string, object>);
|
rawData = default(Dictionary<string, object>);
|
||||||
|
|
||||||
if (parser != null)
|
if (parser != null)
|
||||||
|
@ -237,7 +235,7 @@ namespace SafeExamBrowser.Configuration
|
||||||
var serializer = dataSerializers.FirstOrDefault(s => s.CanSerialize(format));
|
var serializer = dataSerializers.FirstOrDefault(s => s.CanSerialize(format));
|
||||||
var status = SaveStatus.NotSupported;
|
var status = SaveStatus.NotSupported;
|
||||||
|
|
||||||
serialized = default(Stream);
|
serialized = default;
|
||||||
|
|
||||||
if (serializer != null)
|
if (serializer != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -213,10 +213,11 @@ namespace SafeExamBrowser.I18n.Contracts
|
||||||
SystemControl_BatteryChargeLowInfo,
|
SystemControl_BatteryChargeLowInfo,
|
||||||
SystemControl_BatteryRemainingCharge,
|
SystemControl_BatteryRemainingCharge,
|
||||||
SystemControl_KeyboardLayoutTooltip,
|
SystemControl_KeyboardLayoutTooltip,
|
||||||
SystemControl_WirelessConnected,
|
SystemControl_NetworkDisconnected,
|
||||||
SystemControl_WirelessConnecting,
|
SystemControl_NetworkNotAvailable,
|
||||||
SystemControl_WirelessDisconnected,
|
SystemControl_NetworkWiredConnected,
|
||||||
SystemControl_WirelessNotAvailable,
|
SystemControl_NetworkWirelessConnected,
|
||||||
|
SystemControl_NetworkWirelessConnecting,
|
||||||
Version
|
Version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,17 +597,20 @@
|
||||||
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
||||||
Das aktuelle Tastatur-Layout ist "%%LAYOUT%%"
|
Das aktuelle Tastatur-Layout ist "%%LAYOUT%%"
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessConnected">
|
<Entry key="SystemControl_NetworkDisconnected">
|
||||||
Verbunden mit "%%NAME%%"
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessConnecting">
|
|
||||||
Verbinde...
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessDisconnected">
|
|
||||||
Getrennt
|
Getrennt
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessNotAvailable">
|
<Entry key="SystemControl_NetworkNotAvailable">
|
||||||
Kein WLAN-Netzwerkadapter verfügbar oder eingestellt
|
Kein Netzwerkadapter verfügbar oder eingestellt
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWiredConnected">
|
||||||
|
Verbunden
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnected">
|
||||||
|
Verbunden mit "%%NAME%%"
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnecting">
|
||||||
|
Verbinde...
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="Version">
|
<Entry key="Version">
|
||||||
Version
|
Version
|
||||||
|
|
|
@ -597,18 +597,21 @@
|
||||||
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
||||||
The current keyboard layout is "%%LAYOUT%%"
|
The current keyboard layout is "%%LAYOUT%%"
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessConnected">
|
<Entry key="SystemControl_NetworkDisconnected">
|
||||||
Connected to "%%NAME%%"
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessConnecting">
|
|
||||||
Connecting...
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessDisconnected">
|
|
||||||
Disconnected
|
Disconnected
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessNotAvailable">
|
<Entry key="SystemControl_NetworkNotAvailable">
|
||||||
No wireless network adapter available or turned on
|
No wireless network adapter available or turned on
|
||||||
</Entry>
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWiredConnected">
|
||||||
|
Connected
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnected">
|
||||||
|
Connected to "%%NAME%%"
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnecting">
|
||||||
|
Connecting...
|
||||||
|
</Entry>
|
||||||
<Entry key="Version">
|
<Entry key="Version">
|
||||||
Version
|
Version
|
||||||
</Entry>
|
</Entry>
|
||||||
|
|
|
@ -597,18 +597,21 @@
|
||||||
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
||||||
La disposition actuelle du clavier est "%%LAYOUT%%"
|
La disposition actuelle du clavier est "%%LAYOUT%%"
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessConnected">
|
<Entry key="SystemControl_NetworkDisconnected">
|
||||||
Connecté à "%%NAME%%"
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessConnecting">
|
|
||||||
Connection en cours...
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessDisconnected">
|
|
||||||
Déconnecté
|
Déconnecté
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessNotAvailable">
|
<Entry key="SystemControl_NetworkNotAvailable">
|
||||||
Pas d'adaptateur réseau sans fil disponible ou allumé
|
Pas d'adaptateur réseau sans fil disponible ou allumé
|
||||||
</Entry>
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWiredConnected">
|
||||||
|
Connecté
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnected">
|
||||||
|
Connecté à "%%NAME%%"
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnecting">
|
||||||
|
Connection en cours...
|
||||||
|
</Entry>
|
||||||
<Entry key="Version">
|
<Entry key="Version">
|
||||||
Version
|
Version
|
||||||
</Entry>
|
</Entry>
|
||||||
|
|
|
@ -597,18 +597,21 @@
|
||||||
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
||||||
L'attuale layout della tastiera è "%%LAYOUT%%"
|
L'attuale layout della tastiera è "%%LAYOUT%%"
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessConnected">
|
<Entry key="SystemControl_NetworkDisconnected">
|
||||||
Collegato a "%%NAME%%"
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessConnecting">
|
|
||||||
Collegamento...
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessDisconnected">
|
|
||||||
Disconnesso
|
Disconnesso
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessNotAvailable">
|
<Entry key="SystemControl_NetworkNotAvailable">
|
||||||
Nessun adattatore di rete wireless disponibile o attivato
|
Nessun adattatore di rete wireless disponibile o attivato
|
||||||
</Entry>
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWiredConnected">
|
||||||
|
Collegato
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnected">
|
||||||
|
Collegato a "%%NAME%%"
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnecting">
|
||||||
|
Collegamento...
|
||||||
|
</Entry>
|
||||||
<Entry key="Version">
|
<Entry key="Version">
|
||||||
Versione
|
Versione
|
||||||
</Entry>
|
</Entry>
|
||||||
|
|
|
@ -531,18 +531,21 @@
|
||||||
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
<Entry key="SystemControl_KeyboardLayoutTooltip">
|
||||||
当前键盘布局是 "%%LAYOUT%%"
|
当前键盘布局是 "%%LAYOUT%%"
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessConnected">
|
<Entry key="SystemControl_NetworkDisconnected">
|
||||||
已连接到 "%%NAME%%"
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessConnecting">
|
|
||||||
正在连接...
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SystemControl_WirelessDisconnected">
|
|
||||||
连接已断开
|
连接已断开
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SystemControl_WirelessNotAvailable">
|
<Entry key="SystemControl_NetworkNotAvailable">
|
||||||
没有无线网卡或未启用无线网卡
|
没有无线网卡或未启用无线网卡
|
||||||
</Entry>
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWiredConnected">
|
||||||
|
连接的
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnected">
|
||||||
|
已连接到 "%%NAME%%"
|
||||||
|
</Entry>
|
||||||
|
<Entry key="SystemControl_NetworkWirelessConnecting">
|
||||||
|
正在连接...
|
||||||
|
</Entry>
|
||||||
<Entry key="Version">
|
<Entry key="Version">
|
||||||
版本
|
版本
|
||||||
</Entry>
|
</Entry>
|
||||||
|
|
|
@ -149,7 +149,7 @@ namespace SafeExamBrowser.Runtime
|
||||||
var xmlParser = new XmlParser(compressor, ModuleLogger(nameof(XmlParser)));
|
var xmlParser = new XmlParser(compressor, ModuleLogger(nameof(XmlParser)));
|
||||||
var xmlSerializer = new XmlSerializer(ModuleLogger(nameof(XmlSerializer)));
|
var xmlSerializer = new XmlSerializer(ModuleLogger(nameof(XmlSerializer)));
|
||||||
|
|
||||||
configuration = new ConfigurationRepository(certificateStore, new HashAlgorithm(), repositoryLogger);
|
configuration = new ConfigurationRepository(certificateStore, repositoryLogger);
|
||||||
appConfig = configuration.InitializeAppConfig();
|
appConfig = configuration.InitializeAppConfig();
|
||||||
|
|
||||||
configuration.Register(new BinaryParser(
|
configuration.Register(new BinaryParser(
|
||||||
|
|
|
@ -26,8 +26,8 @@ using SafeExamBrowser.Server.Data;
|
||||||
using SafeExamBrowser.Settings.Logging;
|
using SafeExamBrowser.Settings.Logging;
|
||||||
using SafeExamBrowser.Settings.Server;
|
using SafeExamBrowser.Settings.Server;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts;
|
using SafeExamBrowser.SystemComponents.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
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
|
||||||
|
@ -45,7 +45,7 @@ namespace SafeExamBrowser.Server
|
||||||
private readonly IPowerSupply powerSupply;
|
private readonly IPowerSupply powerSupply;
|
||||||
private readonly ISystemInfo systemInfo;
|
private readonly ISystemInfo systemInfo;
|
||||||
private readonly IUserInfo userInfo;
|
private readonly IUserInfo userInfo;
|
||||||
private readonly IWirelessAdapter wirelessAdapter;
|
private readonly INetworkAdapter networkAdapter;
|
||||||
|
|
||||||
private ApiVersion1 api;
|
private ApiVersion1 api;
|
||||||
private string connectionToken;
|
private string connectionToken;
|
||||||
|
@ -70,7 +70,7 @@ namespace SafeExamBrowser.Server
|
||||||
ISystemInfo systemInfo,
|
ISystemInfo systemInfo,
|
||||||
IUserInfo userInfo,
|
IUserInfo userInfo,
|
||||||
IPowerSupply powerSupply = default,
|
IPowerSupply powerSupply = default,
|
||||||
IWirelessAdapter wirelessAdapter = default)
|
INetworkAdapter networkAdapter = default)
|
||||||
{
|
{
|
||||||
this.api = new ApiVersion1();
|
this.api = new ApiVersion1();
|
||||||
this.appConfig = appConfig;
|
this.appConfig = appConfig;
|
||||||
|
@ -79,12 +79,12 @@ namespace SafeExamBrowser.Server
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.logContent = new ConcurrentQueue<ILogContent>();
|
this.logContent = new ConcurrentQueue<ILogContent>();
|
||||||
this.logTimer = new Timer();
|
this.logTimer = new Timer();
|
||||||
|
this.networkAdapter = networkAdapter;
|
||||||
this.parser = new Parser(logger);
|
this.parser = new Parser(logger);
|
||||||
this.pingTimer = new Timer();
|
this.pingTimer = new Timer();
|
||||||
this.powerSupply = powerSupply;
|
this.powerSupply = powerSupply;
|
||||||
this.systemInfo = systemInfo;
|
this.systemInfo = systemInfo;
|
||||||
this.userInfo = userInfo;
|
this.userInfo = userInfo;
|
||||||
this.wirelessAdapter = wirelessAdapter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerResponse Connect()
|
public ServerResponse Connect()
|
||||||
|
@ -226,7 +226,7 @@ namespace SafeExamBrowser.Server
|
||||||
public void Initialize(ServerSettings settings)
|
public void Initialize(ServerSettings settings)
|
||||||
{
|
{
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
|
||||||
httpClient = new HttpClient();
|
httpClient = new HttpClient();
|
||||||
httpClient.BaseAddress = new Uri(settings.ServerUrl);
|
httpClient.BaseAddress = new Uri(settings.ServerUrl);
|
||||||
|
|
||||||
|
@ -348,20 +348,20 @@ namespace SafeExamBrowser.Server
|
||||||
pingTimer.Start();
|
pingTimer.Start();
|
||||||
logger.Info("Started sending pings.");
|
logger.Info("Started sending pings.");
|
||||||
|
|
||||||
if (powerSupply != default(IPowerSupply) && wirelessAdapter != default(IWirelessAdapter))
|
if (powerSupply != default && networkAdapter != default)
|
||||||
{
|
{
|
||||||
powerSupply.StatusChanged += PowerSupply_StatusChanged;
|
powerSupply.StatusChanged += PowerSupply_StatusChanged;
|
||||||
wirelessAdapter.NetworksChanged += WirelessAdapter_NetworksChanged;
|
networkAdapter.Changed += NetworkAdapter_Changed;
|
||||||
logger.Info("Started monitoring system components.");
|
logger.Info("Started monitoring system components.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopConnectivity()
|
public void StopConnectivity()
|
||||||
{
|
{
|
||||||
if (powerSupply != default(IPowerSupply) && wirelessAdapter != default(IWirelessAdapter))
|
if (powerSupply != default && networkAdapter != default)
|
||||||
{
|
{
|
||||||
powerSupply.StatusChanged -= PowerSupply_StatusChanged;
|
powerSupply.StatusChanged -= PowerSupply_StatusChanged;
|
||||||
wirelessAdapter.NetworksChanged -= WirelessAdapter_NetworksChanged;
|
networkAdapter.Changed -= NetworkAdapter_Changed;
|
||||||
logger.Info("Stopped monitoring system components.");
|
logger.Info("Stopped monitoring system components.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +477,7 @@ namespace SafeExamBrowser.Server
|
||||||
SendPowerSupplyStatus(text, value);
|
SendPowerSupplyStatus(text, value);
|
||||||
currentPowerSupplyValue = value;
|
currentPowerSupplyValue = value;
|
||||||
}
|
}
|
||||||
else if (connected != connectedToPowergrid)
|
else if (connected != connectedToPowergrid)
|
||||||
{
|
{
|
||||||
var text = $"<battery> Device has been {(connected ? "connected to" : "disconnected from")} power grid";
|
var text = $"<battery> Device has been {(connected ? "connected to" : "disconnected from")} power grid";
|
||||||
SendPowerSupplyStatus(text, value);
|
SendPowerSupplyStatus(text, value);
|
||||||
|
@ -507,13 +507,13 @@ namespace SafeExamBrowser.Server
|
||||||
TryExecute(HttpMethod.Post, api.LogEndpoint, out _, content, contentType, authorization, token);
|
TryExecute(HttpMethod.Post, api.LogEndpoint, out _, content, contentType, authorization, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WirelessAdapter_NetworksChanged()
|
private void NetworkAdapter_Changed()
|
||||||
{
|
{
|
||||||
const int NOT_CONNECTED = -1;
|
const int NOT_CONNECTED = -1;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var network = wirelessAdapter.GetNetworks().FirstOrDefault(n => n.Status == WirelessNetworkStatus.Connected);
|
var network = networkAdapter.GetWirelessNetworks().FirstOrDefault(n => n.Status == ConnectionStatus.Connected);
|
||||||
|
|
||||||
if (network?.SignalStrength != currentWlanValue)
|
if (network?.SignalStrength != currentWlanValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace SafeExamBrowser.Settings.UserInterface
|
||||||
/// Determines whether the application log is accessible via the action center.
|
/// Determines whether the application log is accessible via the action center.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShowApplicationLog { get; set; }
|
public bool ShowApplicationLog { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the system control for audio is accessible via the action center.
|
/// Determines whether the system control for audio is accessible via the action center.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -47,8 +47,8 @@ namespace SafeExamBrowser.Settings.UserInterface
|
||||||
public bool ShowKeyboardLayout { get; set; }
|
public bool ShowKeyboardLayout { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the system control for the wireless network is accessible via the action center.
|
/// Determines whether the system control for the network is accessible via the action center.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShowWirelessNetwork { get; set; }
|
public bool ShowNetwork { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,8 @@ namespace SafeExamBrowser.Settings.UserInterface
|
||||||
public bool ShowKeyboardLayout { get; set; }
|
public bool ShowKeyboardLayout { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the system control for the wireless network is accessible via the taskbar.
|
/// Determines whether the system control for the network is accessible via the taskbar.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShowWirelessNetwork { get; set; }
|
public bool ShowNetwork { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,16 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork
|
namespace SafeExamBrowser.SystemComponents.Contracts.Network
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines all possible wireless network statuses which can be determined by the application.
|
/// Defines all possible connection statuses which can be determined by the application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum WirelessNetworkStatus
|
public enum ConnectionStatus
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The connection status is not determinable.
|
||||||
|
/// </summary>
|
||||||
Undefined = 0,
|
Undefined = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.SystemComponents.Contracts.Network
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines all possible connection types which can be determined by the application.
|
||||||
|
/// </summary>
|
||||||
|
public enum ConnectionType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The connection type cannot be determined.
|
||||||
|
/// </summary>
|
||||||
|
Undefined = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A wired network connection.
|
||||||
|
/// </summary>
|
||||||
|
Wired,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A wireless network connection.
|
||||||
|
/// </summary>
|
||||||
|
Wireless
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,10 +6,10 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork.Events
|
namespace SafeExamBrowser.SystemComponents.Contracts.Network.Events
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates that the available wireless networks have changed.
|
/// Indicates that the network adapter has changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public delegate void NetworksChangedEventHandler();
|
public delegate void ChangedEventHandler();
|
||||||
}
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network.Events;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.SystemComponents.Contracts.Network
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the functionality of the network adapter system component.
|
||||||
|
/// </summary>
|
||||||
|
public interface INetworkAdapter : ISystemComponent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The connection status of the network adapter.
|
||||||
|
/// </summary>
|
||||||
|
ConnectionStatus Status { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The type of the current network connection.
|
||||||
|
/// </summary>
|
||||||
|
ConnectionType Type { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when the network adapter has changed.
|
||||||
|
/// </summary>
|
||||||
|
event ChangedEventHandler Changed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to connect to the wireless network with the given ID.
|
||||||
|
/// </summary>
|
||||||
|
void ConnectToWirelessNetwork(Guid id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves all currently available wireless networks.
|
||||||
|
/// </summary>
|
||||||
|
IEnumerable<IWirelessNetwork> GetWirelessNetworks();
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork
|
namespace SafeExamBrowser.SystemComponents.Contracts.Network
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines a wireless network which can be connected to by the application.
|
/// Defines a wireless network which can be connected to by the application.
|
||||||
|
@ -33,6 +33,6 @@ namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The connection status of this network.
|
/// The connection status of this network.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WirelessNetworkStatus Status { get; }
|
ConnectionStatus Status { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -59,6 +59,7 @@
|
||||||
<Compile Include="IFileSystem.cs" />
|
<Compile Include="IFileSystem.cs" />
|
||||||
<Compile Include="IRemoteSessionDetector.cs" />
|
<Compile Include="IRemoteSessionDetector.cs" />
|
||||||
<Compile Include="IVirtualMachineDetector.cs" />
|
<Compile Include="IVirtualMachineDetector.cs" />
|
||||||
|
<Compile Include="Network\ConnectionType.cs" />
|
||||||
<Compile Include="PowerSupply\Events\StatusChangedEventHandler.cs" />
|
<Compile Include="PowerSupply\Events\StatusChangedEventHandler.cs" />
|
||||||
<Compile Include="PowerSupply\IPowerSupply.cs" />
|
<Compile Include="PowerSupply\IPowerSupply.cs" />
|
||||||
<Compile Include="PowerSupply\BatteryChargeStatus.cs" />
|
<Compile Include="PowerSupply\BatteryChargeStatus.cs" />
|
||||||
|
@ -68,14 +69,13 @@
|
||||||
<Compile Include="ISystemComponent.cs" />
|
<Compile Include="ISystemComponent.cs" />
|
||||||
<Compile Include="ISystemInfo.cs" />
|
<Compile Include="ISystemInfo.cs" />
|
||||||
<Compile Include="IUserInfo.cs" />
|
<Compile Include="IUserInfo.cs" />
|
||||||
<Compile Include="WirelessNetwork\Events\NetworksChangedEventHandler.cs" />
|
<Compile Include="Network\Events\ChangedEventHandler.cs" />
|
||||||
<Compile Include="WirelessNetwork\Events\StatusChangedEventHandler.cs" />
|
<Compile Include="Network\INetworkAdapter.cs" />
|
||||||
<Compile Include="WirelessNetwork\IWirelessAdapter.cs" />
|
<Compile Include="Network\IWirelessNetwork.cs" />
|
||||||
<Compile Include="WirelessNetwork\IWirelessNetwork.cs" />
|
|
||||||
<Compile Include="OperatingSystem.cs" />
|
<Compile Include="OperatingSystem.cs" />
|
||||||
<Compile Include="PowerSupply\IPowerSupplyStatus.cs" />
|
<Compile Include="PowerSupply\IPowerSupplyStatus.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="WirelessNetwork\WirelessNetworkStatus.cs" />
|
<Compile Include="Network\ConnectionStatus.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork.Events
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates that the wireless network status has changed.
|
|
||||||
/// </summary>
|
|
||||||
public delegate void StatusChangedEventHandler(WirelessNetworkStatus status);
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork.Events;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork
|
|
||||||
{
|
|
||||||
public interface IWirelessAdapter : ISystemComponent
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Fired when the available wireless networks changed.
|
|
||||||
/// </summary>
|
|
||||||
event NetworksChangedEventHandler NetworksChanged;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fired when the wireless network status changed.
|
|
||||||
/// </summary>
|
|
||||||
event StatusChangedEventHandler StatusChanged;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates whether the system has an active wireless network adapter.
|
|
||||||
/// </summary>
|
|
||||||
bool IsAvailable { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to connect to the wireless network with the given ID.
|
|
||||||
/// </summary>
|
|
||||||
void Connect(Guid id);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves all currently available networks.
|
|
||||||
/// </summary>
|
|
||||||
IEnumerable<IWirelessNetwork> GetNetworks();
|
|
||||||
}
|
|
||||||
}
|
|
215
SafeExamBrowser.SystemComponents/Network/NetworkAdapter.cs
Normal file
215
SafeExamBrowser.SystemComponents/Network/NetworkAdapter.cs
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Timers;
|
||||||
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network.Events;
|
||||||
|
using SafeExamBrowser.WindowsApi.Contracts;
|
||||||
|
using SimpleWifi;
|
||||||
|
using SimpleWifi.Win32;
|
||||||
|
using SimpleWifi.Win32.Interop;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.SystemComponents.Network
|
||||||
|
{
|
||||||
|
public class NetworkAdapter : INetworkAdapter
|
||||||
|
{
|
||||||
|
private readonly object @lock = new object();
|
||||||
|
private readonly ILogger logger;
|
||||||
|
private readonly INativeMethods nativeMethods;
|
||||||
|
private readonly List<WirelessNetwork> wirelessNetworks;
|
||||||
|
|
||||||
|
private Timer timer;
|
||||||
|
private Wifi wifi;
|
||||||
|
|
||||||
|
public ConnectionStatus Status { get; private set; }
|
||||||
|
public ConnectionType Type { get; private set; }
|
||||||
|
|
||||||
|
public event ChangedEventHandler Changed;
|
||||||
|
|
||||||
|
public NetworkAdapter(ILogger logger, INativeMethods nativeMethods)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
this.nativeMethods = nativeMethods;
|
||||||
|
this.wirelessNetworks = new List<WirelessNetwork>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConnectToWirelessNetwork(Guid id)
|
||||||
|
{
|
||||||
|
lock (@lock)
|
||||||
|
{
|
||||||
|
var network = wirelessNetworks.FirstOrDefault(n => n.Id == id);
|
||||||
|
|
||||||
|
if (network != default)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var request = new AuthRequest(network.AccessPoint);
|
||||||
|
|
||||||
|
logger.Info($"Attempting to connect to '{network.Name}'...");
|
||||||
|
|
||||||
|
network.AccessPoint.ConnectAsync(request, false, (success) => AccessPoint_OnConnectCompleted(network.Name, success));
|
||||||
|
Status = ConnectionStatus.Connecting;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error($"Failed to connect to wireless network '{network.Name}!'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Warn($"Could not find network with id '{id}'!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Changed?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<IWirelessNetwork> GetWirelessNetworks()
|
||||||
|
{
|
||||||
|
lock (@lock)
|
||||||
|
{
|
||||||
|
return new List<WirelessNetwork>(wirelessNetworks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
const int FIVE_SECONDS = 5000;
|
||||||
|
|
||||||
|
NetworkChange.NetworkAddressChanged += (o, args) => Update();
|
||||||
|
NetworkChange.NetworkAvailabilityChanged += (o, args) => Update();
|
||||||
|
|
||||||
|
wifi = new Wifi();
|
||||||
|
wifi.ConnectionStatusChanged += (o, args) => Update();
|
||||||
|
|
||||||
|
timer = new Timer(FIVE_SECONDS);
|
||||||
|
timer.Elapsed += (o, args) => Update();
|
||||||
|
timer.AutoReset = true;
|
||||||
|
timer.Start();
|
||||||
|
|
||||||
|
Update();
|
||||||
|
|
||||||
|
logger.Info("Started monitoring the network adapter.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Terminate()
|
||||||
|
{
|
||||||
|
if (timer != null)
|
||||||
|
{
|
||||||
|
timer.Stop();
|
||||||
|
logger.Info("Stopped monitoring the network adapter.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AccessPoint_OnConnectCompleted(string name, bool success)
|
||||||
|
{
|
||||||
|
lock (@lock)
|
||||||
|
{
|
||||||
|
// This handler seems to be called before the connection has been fully established, thus we don't yet set the status to connected...
|
||||||
|
Status = success ? ConnectionStatus.Connecting : ConnectionStatus.Disconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
logger.Info($"Successfully connected to wireless network '{name}'.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Error($"Failed to connect to wireless network '{name}!'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lock (@lock)
|
||||||
|
{
|
||||||
|
var hasInternet = nativeMethods.HasInternetConnection();
|
||||||
|
var hasWireless = !wifi.NoWifiAvailable && !IsTurnedOff();
|
||||||
|
var isConnecting = Status == ConnectionStatus.Connecting;
|
||||||
|
var previousStatus = Status;
|
||||||
|
|
||||||
|
wirelessNetworks.Clear();
|
||||||
|
|
||||||
|
if (hasWireless)
|
||||||
|
{
|
||||||
|
foreach (var accessPoint in wifi.GetAccessPoints())
|
||||||
|
{
|
||||||
|
// The user may only connect to an already configured or connected wireless network!
|
||||||
|
if (accessPoint.HasProfile || accessPoint.IsConnected)
|
||||||
|
{
|
||||||
|
wirelessNetworks.Add(ToWirelessNetwork(accessPoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Type = hasWireless ? ConnectionType.Wireless : (hasInternet ? ConnectionType.Wired : ConnectionType.Undefined);
|
||||||
|
Status = hasInternet ? ConnectionStatus.Connected : (hasWireless && isConnecting ? ConnectionStatus.Connecting : ConnectionStatus.Disconnected);
|
||||||
|
|
||||||
|
if (previousStatus != ConnectionStatus.Connected && Status == ConnectionStatus.Connected)
|
||||||
|
{
|
||||||
|
logger.Info("Connection established.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousStatus != ConnectionStatus.Disconnected && Status == ConnectionStatus.Disconnected)
|
||||||
|
{
|
||||||
|
logger.Info("Connection lost.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error("Failed to update network adapter!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Changed?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsTurnedOff()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var client = new WlanClient();
|
||||||
|
|
||||||
|
foreach (var @interface in client.Interfaces)
|
||||||
|
{
|
||||||
|
foreach (var state in @interface.RadioState.PhyRadioState)
|
||||||
|
{
|
||||||
|
if (state.dot11SoftwareRadioState == Dot11RadioState.On && state.dot11HardwareRadioState == Dot11RadioState.On)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error("Failed to determine the radio state of the wireless adapter(s)! Assuming it is (all are) turned off...", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WirelessNetwork ToWirelessNetwork(AccessPoint accessPoint)
|
||||||
|
{
|
||||||
|
return new WirelessNetwork
|
||||||
|
{
|
||||||
|
AccessPoint = accessPoint,
|
||||||
|
Name = accessPoint.Name,
|
||||||
|
SignalStrength = Convert.ToInt32(accessPoint.SignalStrength),
|
||||||
|
Status = accessPoint.IsConnected ? ConnectionStatus.Connected : ConnectionStatus.Disconnected
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,10 +7,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SimpleWifi;
|
using SimpleWifi;
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents.WirelessNetwork
|
namespace SafeExamBrowser.SystemComponents.Network
|
||||||
{
|
{
|
||||||
internal class WirelessNetwork : IWirelessNetwork
|
internal class WirelessNetwork : IWirelessNetwork
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ namespace SafeExamBrowser.SystemComponents.WirelessNetwork
|
||||||
public Guid Id { get; }
|
public Guid Id { get; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public int SignalStrength { get; set; }
|
public int SignalStrength { get; set; }
|
||||||
public WirelessNetworkStatus Status { get; set; }
|
public ConnectionStatus Status { get; set; }
|
||||||
|
|
||||||
public WirelessNetwork()
|
public WirelessNetwork()
|
||||||
{
|
{
|
|
@ -101,8 +101,8 @@
|
||||||
<Compile Include="SystemInfo.cs" />
|
<Compile Include="SystemInfo.cs" />
|
||||||
<Compile Include="UserInfo.cs" />
|
<Compile Include="UserInfo.cs" />
|
||||||
<Compile Include="VirtualMachineDetector.cs" />
|
<Compile Include="VirtualMachineDetector.cs" />
|
||||||
<Compile Include="WirelessNetwork\WirelessAdapter.cs" />
|
<Compile Include="Network\NetworkAdapter.cs" />
|
||||||
<Compile Include="WirelessNetwork\WirelessNetwork.cs" />
|
<Compile Include="Network\WirelessNetwork.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
|
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
|
||||||
|
@ -117,6 +117,10 @@
|
||||||
<Project>{903129c6-e236-493b-9ad6-c6a57f647a3a}</Project>
|
<Project>{903129c6-e236-493b-9ad6-c6a57f647a3a}</Project>
|
||||||
<Name>SafeExamBrowser.SystemComponents.Contracts</Name>
|
<Name>SafeExamBrowser.SystemComponents.Contracts</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\SafeExamBrowser.WindowsApi.Contracts\SafeExamBrowser.WindowsApi.Contracts.csproj">
|
||||||
|
<Project>{7016f080-9aa5-41b2-a225-385ad877c171}</Project>
|
||||||
|
<Name>SafeExamBrowser.WindowsApi.Contracts</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.config" />
|
<None Include="app.config" />
|
||||||
|
|
|
@ -1,203 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Timers;
|
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork.Events;
|
|
||||||
using SimpleWifi;
|
|
||||||
using SimpleWifi.Win32;
|
|
||||||
using SimpleWifi.Win32.Interop;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.SystemComponents.WirelessNetwork
|
|
||||||
{
|
|
||||||
public class WirelessAdapter : IWirelessAdapter
|
|
||||||
{
|
|
||||||
private readonly object @lock = new object();
|
|
||||||
|
|
||||||
private List<WirelessNetwork> networks;
|
|
||||||
private ILogger logger;
|
|
||||||
private Timer timer;
|
|
||||||
private Wifi wifi;
|
|
||||||
|
|
||||||
public bool IsAvailable { get; private set; }
|
|
||||||
|
|
||||||
public event NetworksChangedEventHandler NetworksChanged;
|
|
||||||
public event StatusChangedEventHandler StatusChanged;
|
|
||||||
|
|
||||||
public WirelessAdapter(ILogger logger)
|
|
||||||
{
|
|
||||||
this.logger = logger;
|
|
||||||
this.networks = new List<WirelessNetwork>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Connect(Guid id)
|
|
||||||
{
|
|
||||||
lock (@lock)
|
|
||||||
{
|
|
||||||
var network = networks.FirstOrDefault(n => n.Id == id);
|
|
||||||
|
|
||||||
if (network != default(WirelessNetwork))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var request = new AuthRequest(network.AccessPoint);
|
|
||||||
|
|
||||||
logger.Info($"Attempting to connect to '{network.Name}'...");
|
|
||||||
network.AccessPoint.ConnectAsync(request, false, (success) => AccessPoint_OnConnectCompleted(network.Name, success));
|
|
||||||
StatusChanged?.Invoke(WirelessNetworkStatus.Connecting);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.Error($"Failed to connect to wireless network '{network.Name}!'", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Warn($"Could not find network with id '{id}'!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<IWirelessNetwork> GetNetworks()
|
|
||||||
{
|
|
||||||
lock (@lock)
|
|
||||||
{
|
|
||||||
return new List<WirelessNetwork>(networks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
const int FIVE_SECONDS = 5000;
|
|
||||||
|
|
||||||
wifi = new Wifi();
|
|
||||||
wifi.ConnectionStatusChanged += Wifi_ConnectionStatusChanged;
|
|
||||||
IsAvailable = !wifi.NoWifiAvailable && !IsTurnedOff();
|
|
||||||
|
|
||||||
if (IsAvailable)
|
|
||||||
{
|
|
||||||
UpdateAvailableNetworks();
|
|
||||||
|
|
||||||
timer = new Timer(FIVE_SECONDS);
|
|
||||||
timer.Elapsed += Timer_Elapsed;
|
|
||||||
timer.AutoReset = true;
|
|
||||||
timer.Start();
|
|
||||||
|
|
||||||
logger.Info("Started monitoring the wireless network adapter.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Info("Wireless networks cannot be monitored, as there is no hardware adapter available or it is turned off.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Terminate()
|
|
||||||
{
|
|
||||||
if (timer != null)
|
|
||||||
{
|
|
||||||
timer.Stop();
|
|
||||||
logger.Info("Stopped monitoring the wireless network adapter.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AccessPoint_OnConnectCompleted(string name, bool success)
|
|
||||||
{
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
logger.Info($"Successfully connected to wireless network '{name}'.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Error($"Failed to connect to wireless network '{name}!'");
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateAvailableNetworks();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
|
||||||
{
|
|
||||||
UpdateAvailableNetworks();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Wifi_ConnectionStatusChanged(object sender, WifiStatusEventArgs e)
|
|
||||||
{
|
|
||||||
UpdateAvailableNetworks();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsTurnedOff()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new WlanClient();
|
|
||||||
|
|
||||||
foreach (var @interface in client.Interfaces)
|
|
||||||
{
|
|
||||||
foreach (var state in @interface.RadioState.PhyRadioState)
|
|
||||||
{
|
|
||||||
if (state.dot11SoftwareRadioState == Dot11RadioState.On && state.dot11HardwareRadioState == Dot11RadioState.On)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.Error("Failed to determine the radio state of the wireless adapter(s)! Assuming it is (all are) turned off...", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateAvailableNetworks()
|
|
||||||
{
|
|
||||||
lock (@lock)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
networks.Clear();
|
|
||||||
|
|
||||||
foreach (var accessPoint in wifi.GetAccessPoints())
|
|
||||||
{
|
|
||||||
// The user may only connect to an already configured or connected wireless network!
|
|
||||||
if (accessPoint.HasProfile || accessPoint.IsConnected)
|
|
||||||
{
|
|
||||||
networks.Add(ToNetwork(accessPoint));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworksChanged?.Invoke();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.Error("Failed to update available networks!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private WirelessNetwork ToNetwork(AccessPoint accessPoint)
|
|
||||||
{
|
|
||||||
return new WirelessNetwork
|
|
||||||
{
|
|
||||||
AccessPoint = accessPoint,
|
|
||||||
Name = accessPoint.Name,
|
|
||||||
SignalStrength = Convert.ToInt32(accessPoint.SignalStrength),
|
|
||||||
Status = accessPoint.IsConnected ? WirelessNetworkStatus.Connected : WirelessNetworkStatus.Disconnected
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private WirelessNetworkStatus ToStatus(WifiStatus status)
|
|
||||||
{
|
|
||||||
return status == WifiStatus.Connected ? WirelessNetworkStatus.Connected : WirelessNetworkStatus.Disconnected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,8 +18,8 @@ using SafeExamBrowser.Settings.Browser;
|
||||||
using SafeExamBrowser.Settings.Proctoring;
|
using SafeExamBrowser.Settings.Proctoring;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
|
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
|
@ -78,6 +78,11 @@ namespace SafeExamBrowser.UserInterface.Contracts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IWindow CreateLogWindow(ILogger logger);
|
IWindow CreateLogWindow(ILogger logger);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a system control which allows to view and/or change the network connection of the computer.
|
||||||
|
/// </summary>
|
||||||
|
ISystemControl CreateNetworkControl(INetworkAdapter adapter, Location location);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a notification control for the given notification, initialized for the specified location.
|
/// Creates a notification control for the given notification, initialized for the specified location.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -132,10 +137,5 @@ namespace SafeExamBrowser.UserInterface.Contracts
|
||||||
/// Creates a new taskview.
|
/// Creates a new taskview.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ITaskview CreateTaskview();
|
ITaskview CreateTaskview();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a system control which allows to change the wireless network connection of the computer.
|
|
||||||
/// </summary>
|
|
||||||
ISystemControl CreateWirelessNetworkControl(IWirelessAdapter wirelessAdapter, Location location);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter.WirelessNetworkButton" x:ClassModifier="internal"
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter.NetworkButton" x:ClassModifier="internal"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
@ -9,17 +9,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter
|
namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter
|
||||||
{
|
{
|
||||||
internal partial class WirelessNetworkButton : UserControl
|
internal partial class NetworkButton : UserControl
|
||||||
{
|
{
|
||||||
private IWirelessNetwork network;
|
private readonly IWirelessNetwork network;
|
||||||
|
|
||||||
internal event EventHandler NetworkSelected;
|
internal event EventHandler NetworkSelected;
|
||||||
|
|
||||||
internal WirelessNetworkButton(IWirelessNetwork network)
|
internal NetworkButton(IWirelessNetwork network)
|
||||||
{
|
{
|
||||||
this.network = network;
|
this.network = network;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter
|
||||||
private void InitializeNetworkButton()
|
private void InitializeNetworkButton()
|
||||||
{
|
{
|
||||||
Button.Click += (o, args) => NetworkSelected?.Invoke(this, EventArgs.Empty);
|
Button.Click += (o, args) => NetworkSelected?.Invoke(this, EventArgs.Empty);
|
||||||
IsCurrentTextBlock.Visibility = network.Status == WirelessNetworkStatus.Connected ? Visibility.Visible : Visibility.Hidden;
|
IsCurrentTextBlock.Visibility = network.Status == ConnectionStatus.Connected ? Visibility.Visible : Visibility.Hidden;
|
||||||
NetworkNameTextBlock.Text = network.Name;
|
NetworkNameTextBlock.Text = network.Name;
|
||||||
SignalStrengthTextBlock.Text = $"{network.SignalStrength}%";
|
SignalStrengthTextBlock.Text = $"{network.SignalStrength}%";
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter.WirelessNetworkControl" x:ClassModifier="internal"
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter.NetworkControl" x:ClassModifier="internal"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<Popup x:Name="Popup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}">
|
<Popup x:Name="Popup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}">
|
||||||
<Border Background="Gray">
|
<Border Background="Gray">
|
||||||
<ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
<ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
||||||
<StackPanel x:Name="NetworksStackPanel" />
|
<StackPanel x:Name="WirelessNetworksStackPanel" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
|
@ -30,10 +30,11 @@
|
||||||
<RowDefinition Height="3*" />
|
<RowDefinition Height="3*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
|
<Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
<Viewbox x:Name="SignalStrengthIcon" Stretch="Uniform" Width="Auto" />
|
<Viewbox x:Name="WirelessIcon" Stretch="Uniform" Width="Auto" Visibility="Collapsed" />
|
||||||
<fa:ImageAwesome x:Name="NoAdapterIcon" Foreground="Red" Icon="Ban" Margin="1" Opacity="0.3" Visibility="Collapsed" />
|
<fa:ImageAwesome x:Name="WiredIcon" Icon="Tv" Margin="0,2,4,4" Visibility="Collapsed" />
|
||||||
<fa:ImageAwesome x:Name="LoadingIcon" Foreground="Black" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" />
|
<Border Background="White" CornerRadius="6" Height="12" HorizontalAlignment="Right" Margin="-3,0" Panel.ZIndex="10" VerticalAlignment="Bottom">
|
||||||
<Image x:Name="NetworkStatusIcon" Height="7" HorizontalAlignment="Right" Margin="-2,0" Panel.ZIndex="10" VerticalAlignment="Bottom" />
|
<fa:ImageAwesome x:Name="NetworkStatusIcon" />
|
||||||
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
<TextBlock Grid.Row="1" x:Name="Text" FontSize="11" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
|
<TextBlock Grid.Row="1" x:Name="Text" FontSize="11" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
|
||||||
</Grid>
|
</Grid>
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using FontAwesome.WPF;
|
||||||
|
using SafeExamBrowser.Core.Contracts.Resources.Icons;
|
||||||
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
|
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter
|
||||||
|
{
|
||||||
|
internal partial class NetworkControl : UserControl, ISystemControl
|
||||||
|
{
|
||||||
|
private readonly INetworkAdapter adapter;
|
||||||
|
private readonly IText text;
|
||||||
|
|
||||||
|
internal NetworkControl(INetworkAdapter adapter, IText text)
|
||||||
|
{
|
||||||
|
this.adapter = adapter;
|
||||||
|
this.text = text;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
InitializeWirelessNetworkControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
Dispatcher.InvokeAsync(() => Popup.IsOpen = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeWirelessNetworkControl()
|
||||||
|
{
|
||||||
|
var originalBrush = Grid.Background;
|
||||||
|
|
||||||
|
adapter.Changed += () => Dispatcher.InvokeAsync(Update);
|
||||||
|
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
||||||
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
||||||
|
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
||||||
|
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
|
||||||
|
Popup.Closed += (o, args) => Grid.Background = originalBrush;
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(0);
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
WirelessNetworksStackPanel.Children.Clear();
|
||||||
|
|
||||||
|
foreach (var network in adapter.GetWirelessNetworks())
|
||||||
|
{
|
||||||
|
var button = new NetworkButton(network);
|
||||||
|
|
||||||
|
button.NetworkSelected += (o, args) => adapter.ConnectToWirelessNetwork(network.Id);
|
||||||
|
|
||||||
|
if (network.Status == ConnectionStatus.Connected)
|
||||||
|
{
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(network.SignalStrength);
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkWirelessConnected).Replace("%%NAME%%", network.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
WirelessNetworksStackPanel.Children.Add(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adapter.Type)
|
||||||
|
{
|
||||||
|
case ConnectionType.Wired:
|
||||||
|
Button.IsEnabled = false;
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkWiredConnected));
|
||||||
|
WiredIcon.Visibility = Visibility.Visible;
|
||||||
|
WirelessIcon.Visibility = Visibility.Collapsed;
|
||||||
|
break;
|
||||||
|
case ConnectionType.Wireless:
|
||||||
|
Button.IsEnabled = true;
|
||||||
|
WiredIcon.Visibility = Visibility.Collapsed;
|
||||||
|
WirelessIcon.Visibility = Visibility.Visible;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Button.IsEnabled = false;
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkNotAvailable));
|
||||||
|
WiredIcon.Visibility = Visibility.Visible;
|
||||||
|
WirelessIcon.Visibility = Visibility.Collapsed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adapter.Status)
|
||||||
|
{
|
||||||
|
case ConnectionStatus.Connected:
|
||||||
|
NetworkStatusIcon.Rotation = 0;
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Globe, Brushes.Green);
|
||||||
|
NetworkStatusIcon.Spin = false;
|
||||||
|
break;
|
||||||
|
case ConnectionStatus.Connecting:
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkWirelessConnecting));
|
||||||
|
NetworkStatusIcon.Rotation = 0;
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Cog, Brushes.DimGray);
|
||||||
|
NetworkStatusIcon.Spin = true;
|
||||||
|
NetworkStatusIcon.SpinDuration = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkDisconnected));
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Ban, Brushes.DarkOrange);
|
||||||
|
NetworkStatusIcon.Spin = false;
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateText(string text)
|
||||||
|
{
|
||||||
|
Button.ToolTip = text;
|
||||||
|
Text.Text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UIElement GetWirelessIcon(int signalStrength)
|
||||||
|
{
|
||||||
|
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
|
||||||
|
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/WiFi_Light_{icon}.xaml");
|
||||||
|
var resource = new XamlIconResource { Uri = uri };
|
||||||
|
|
||||||
|
return IconResourceLoader.Load(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Media;
|
|
||||||
using FontAwesome.WPF;
|
|
||||||
using SafeExamBrowser.Core.Contracts.Resources.Icons;
|
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
|
||||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter
|
|
||||||
{
|
|
||||||
internal partial class WirelessNetworkControl : UserControl, ISystemControl
|
|
||||||
{
|
|
||||||
private IWirelessAdapter wirelessAdapter;
|
|
||||||
private IText text;
|
|
||||||
|
|
||||||
internal WirelessNetworkControl(IWirelessAdapter wirelessAdapter, IText text)
|
|
||||||
{
|
|
||||||
this.wirelessAdapter = wirelessAdapter;
|
|
||||||
this.text = text;
|
|
||||||
|
|
||||||
InitializeComponent();
|
|
||||||
InitializeWirelessNetworkControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => Popup.IsOpen = false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeWirelessNetworkControl()
|
|
||||||
{
|
|
||||||
var originalBrush = Grid.Background;
|
|
||||||
|
|
||||||
SignalStrengthIcon.Child = GetIcon(0);
|
|
||||||
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
|
||||||
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
|
||||||
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
|
|
||||||
Popup.Closed += (o, args) => Grid.Background = originalBrush;
|
|
||||||
|
|
||||||
if (wirelessAdapter.IsAvailable)
|
|
||||||
{
|
|
||||||
wirelessAdapter.NetworksChanged += WirelessAdapter_NetworksChanged;
|
|
||||||
wirelessAdapter.StatusChanged += WirelessAdapter_StatusChanged;
|
|
||||||
UpdateNetworks();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Button.IsEnabled = false;
|
|
||||||
NoAdapterIcon.Visibility = Visibility.Visible;
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessNotAvailable));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WirelessAdapter_NetworksChanged()
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(UpdateNetworks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WirelessAdapter_StatusChanged(WirelessNetworkStatus status)
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => UpdateStatus(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateNetworks()
|
|
||||||
{
|
|
||||||
var status = WirelessNetworkStatus.Disconnected;
|
|
||||||
|
|
||||||
NetworksStackPanel.Children.Clear();
|
|
||||||
|
|
||||||
foreach (var network in wirelessAdapter.GetNetworks())
|
|
||||||
{
|
|
||||||
var button = new WirelessNetworkButton(network);
|
|
||||||
|
|
||||||
button.NetworkSelected += (o, args) => wirelessAdapter.Connect(network.Id);
|
|
||||||
|
|
||||||
if (network.Status == WirelessNetworkStatus.Connected)
|
|
||||||
{
|
|
||||||
status = WirelessNetworkStatus.Connected;
|
|
||||||
SignalStrengthIcon.Child = GetIcon(network.SignalStrength);
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", network.Name));
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworksStackPanel.Children.Add(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateStatus(WirelessNetworkStatus status)
|
|
||||||
{
|
|
||||||
LoadingIcon.Visibility = Visibility.Collapsed;
|
|
||||||
SignalStrengthIcon.Visibility = Visibility.Visible;
|
|
||||||
NetworkStatusIcon.Visibility = Visibility.Visible;
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case WirelessNetworkStatus.Connected:
|
|
||||||
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Check, Brushes.Green);
|
|
||||||
break;
|
|
||||||
case WirelessNetworkStatus.Connecting:
|
|
||||||
LoadingIcon.Visibility = Visibility.Visible;
|
|
||||||
SignalStrengthIcon.Visibility = Visibility.Collapsed;
|
|
||||||
NetworkStatusIcon.Visibility = Visibility.Collapsed;
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessConnecting));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Close, Brushes.Orange);
|
|
||||||
SignalStrengthIcon.Child = GetIcon(0);
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessDisconnected));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateText(string text)
|
|
||||||
{
|
|
||||||
Button.ToolTip = text;
|
|
||||||
Text.Text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UIElement GetIcon(int signalStrength)
|
|
||||||
{
|
|
||||||
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
|
|
||||||
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/WiFi_Light_{icon}.xaml");
|
|
||||||
var resource = new XamlIconResource { Uri = uri };
|
|
||||||
|
|
||||||
return IconResourceLoader.Load(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar.WirelessNetworkButton" x:ClassModifier="internal"
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar.NetworkButton" x:ClassModifier="internal"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
@ -9,17 +9,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
|
namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
|
||||||
{
|
{
|
||||||
internal partial class WirelessNetworkButton : UserControl
|
internal partial class NetworkButton : UserControl
|
||||||
{
|
{
|
||||||
private IWirelessNetwork network;
|
private readonly IWirelessNetwork network;
|
||||||
|
|
||||||
internal event EventHandler NetworkSelected;
|
internal event EventHandler NetworkSelected;
|
||||||
|
|
||||||
internal WirelessNetworkButton(IWirelessNetwork network)
|
internal NetworkButton(IWirelessNetwork network)
|
||||||
{
|
{
|
||||||
this.network = network;
|
this.network = network;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
|
||||||
private void InitializeNetworkButton()
|
private void InitializeNetworkButton()
|
||||||
{
|
{
|
||||||
Button.Click += (o, args) => NetworkSelected?.Invoke(this, EventArgs.Empty);
|
Button.Click += (o, args) => NetworkSelected?.Invoke(this, EventArgs.Empty);
|
||||||
IsCurrentTextBlock.Visibility = network.Status == WirelessNetworkStatus.Connected ? Visibility.Visible : Visibility.Hidden;
|
IsCurrentTextBlock.Visibility = network.Status == ConnectionStatus.Connected ? Visibility.Visible : Visibility.Hidden;
|
||||||
NetworkNameTextBlock.Text = network.Name;
|
NetworkNameTextBlock.Text = network.Name;
|
||||||
SignalStrengthTextBlock.Text = $"{network.SignalStrength}%";
|
SignalStrengthTextBlock.Text = $"{network.SignalStrength}%";
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar.WirelessNetworkControl" x:ClassModifier="internal"
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar.NetworkControl" x:ClassModifier="internal"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
@ -20,16 +20,17 @@
|
||||||
<Popup x:Name="Popup" IsOpen="False" Placement="Custom" PlacementTarget="{Binding ElementName=Button}">
|
<Popup x:Name="Popup" IsOpen="False" Placement="Custom" PlacementTarget="{Binding ElementName=Button}">
|
||||||
<Border Background="LightGray" BorderBrush="Gray" BorderThickness="1,1,1,0">
|
<Border Background="LightGray" BorderBrush="Gray" BorderThickness="1,1,1,0">
|
||||||
<ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
<ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
||||||
<StackPanel x:Name="NetworksStackPanel" />
|
<StackPanel x:Name="WirelessNetworksStackPanel" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
<Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="40">
|
<Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="40">
|
||||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
<Viewbox x:Name="SignalStrengthIcon" Stretch="Uniform" Width="Auto" />
|
<Viewbox x:Name="WirelessIcon" Stretch="Uniform" Width="Auto" Visibility="Collapsed" />
|
||||||
<fa:ImageAwesome x:Name="NoAdapterIcon" Foreground="Red" Icon="Ban" Margin="1" Opacity="0.3" Visibility="Collapsed" />
|
<fa:ImageAwesome x:Name="WiredIcon" Icon="Tv" Margin="0,2,4,4" Visibility="Collapsed" />
|
||||||
<fa:ImageAwesome x:Name="LoadingIcon" Foreground="Gray" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" />
|
<Border Background="{StaticResource BackgroundBrush}" CornerRadius="6" Height="12" HorizontalAlignment="Right" Margin="0,0,-1,1" Panel.ZIndex="10" VerticalAlignment="Bottom">
|
||||||
<Image x:Name="NetworkStatusIcon" Height="7" HorizontalAlignment="Right" Margin="0,2" Panel.ZIndex="10" VerticalAlignment="Bottom" />
|
<fa:ImageAwesome x:Name="NetworkStatusIcon" />
|
||||||
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
|
@ -15,20 +15,20 @@ using System.Windows.Media;
|
||||||
using FontAwesome.WPF;
|
using FontAwesome.WPF;
|
||||||
using SafeExamBrowser.Core.Contracts.Resources.Icons;
|
using SafeExamBrowser.Core.Contracts.Resources.Icons;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
|
namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
|
||||||
{
|
{
|
||||||
internal partial class WirelessNetworkControl : UserControl, ISystemControl
|
internal partial class NetworkControl : UserControl, ISystemControl
|
||||||
{
|
{
|
||||||
private IWirelessAdapter wirelessAdapter;
|
private readonly INetworkAdapter adapter;
|
||||||
private IText text;
|
private readonly IText text;
|
||||||
|
|
||||||
internal WirelessNetworkControl(IWirelessAdapter wirelessAdapter, IText text)
|
internal NetworkControl(INetworkAdapter adapter, IText text)
|
||||||
{
|
{
|
||||||
this.wirelessAdapter = wirelessAdapter;
|
this.adapter = adapter;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -44,11 +44,12 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
|
||||||
{
|
{
|
||||||
var originalBrush = Button.Background;
|
var originalBrush = Button.Background;
|
||||||
|
|
||||||
SignalStrengthIcon.Child = GetIcon(0);
|
adapter.Changed += () => Dispatcher.InvokeAsync(Update);
|
||||||
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
||||||
Popup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
|
Popup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
|
||||||
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(0);
|
||||||
|
|
||||||
Popup.Opened += (o, args) =>
|
Popup.Opened += (o, args) =>
|
||||||
{
|
{
|
||||||
|
@ -62,18 +63,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
|
||||||
Button.Background = originalBrush;
|
Button.Background = originalBrush;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (wirelessAdapter.IsAvailable)
|
Update();
|
||||||
{
|
|
||||||
wirelessAdapter.NetworksChanged += WirelessAdapter_NetworksChanged;
|
|
||||||
wirelessAdapter.StatusChanged += WirelessAdapter_StatusChanged;
|
|
||||||
UpdateNetworks();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Button.IsEnabled = false;
|
|
||||||
NoAdapterIcon.Visibility = Visibility.Visible;
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessNotAvailable));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CustomPopupPlacement[] Popup_PlacementCallback(Size popupSize, Size targetSize, Point offset)
|
private CustomPopupPlacement[] Popup_PlacementCallback(Size popupSize, Size targetSize, Point offset)
|
||||||
|
@ -84,72 +74,70 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WirelessAdapter_NetworksChanged()
|
private void Update()
|
||||||
{
|
{
|
||||||
Dispatcher.InvokeAsync(UpdateNetworks);
|
WirelessNetworksStackPanel.Children.Clear();
|
||||||
}
|
|
||||||
|
|
||||||
private void WirelessAdapter_StatusChanged(WirelessNetworkStatus status)
|
foreach (var network in adapter.GetWirelessNetworks())
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => UpdateStatus(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateNetworks()
|
|
||||||
{
|
|
||||||
var status = WirelessNetworkStatus.Disconnected;
|
|
||||||
|
|
||||||
NetworksStackPanel.Children.Clear();
|
|
||||||
|
|
||||||
foreach (var network in wirelessAdapter.GetNetworks())
|
|
||||||
{
|
{
|
||||||
var button = new WirelessNetworkButton(network);
|
var button = new NetworkButton(network);
|
||||||
|
|
||||||
button.NetworkSelected += (o, args) => wirelessAdapter.Connect(network.Id);
|
button.NetworkSelected += (o, args) => adapter.ConnectToWirelessNetwork(network.Id);
|
||||||
|
|
||||||
if (network.Status == WirelessNetworkStatus.Connected)
|
if (network.Status == ConnectionStatus.Connected)
|
||||||
{
|
{
|
||||||
status = WirelessNetworkStatus.Connected;
|
WirelessIcon.Child = GetWirelessIcon(network.SignalStrength);
|
||||||
SignalStrengthIcon.Child = GetIcon(network.SignalStrength);
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWirelessConnected).Replace("%%NAME%%", network.Name);
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", network.Name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworksStackPanel.Children.Add(button);
|
WirelessNetworksStackPanel.Children.Add(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateStatus(status);
|
switch (adapter.Type)
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateStatus(WirelessNetworkStatus status)
|
|
||||||
{
|
|
||||||
LoadingIcon.Visibility = Visibility.Collapsed;
|
|
||||||
SignalStrengthIcon.Visibility = Visibility.Visible;
|
|
||||||
NetworkStatusIcon.Visibility = Visibility.Visible;
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
{
|
||||||
case WirelessNetworkStatus.Connected:
|
case ConnectionType.Wired:
|
||||||
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Check, Brushes.Green);
|
Button.IsEnabled = false;
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWiredConnected);
|
||||||
|
WiredIcon.Visibility = Visibility.Visible;
|
||||||
|
WirelessIcon.Visibility = Visibility.Collapsed;
|
||||||
break;
|
break;
|
||||||
case WirelessNetworkStatus.Connecting:
|
case ConnectionType.Wireless:
|
||||||
LoadingIcon.Visibility = Visibility.Visible;
|
Button.IsEnabled = true;
|
||||||
SignalStrengthIcon.Visibility = Visibility.Collapsed;
|
WiredIcon.Visibility = Visibility.Collapsed;
|
||||||
NetworkStatusIcon.Visibility = Visibility.Collapsed;
|
WirelessIcon.Visibility = Visibility.Visible;
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessConnecting));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Close, Brushes.Orange);
|
Button.IsEnabled = false;
|
||||||
SignalStrengthIcon.Child = GetIcon(0);
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkNotAvailable);
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessDisconnected));
|
WiredIcon.Visibility = Visibility.Visible;
|
||||||
|
WirelessIcon.Visibility = Visibility.Collapsed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adapter.Status)
|
||||||
|
{
|
||||||
|
case ConnectionStatus.Connected:
|
||||||
|
NetworkStatusIcon.Rotation = 0;
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Globe, Brushes.Green);
|
||||||
|
NetworkStatusIcon.Spin = false;
|
||||||
|
break;
|
||||||
|
case ConnectionStatus.Connecting:
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWirelessConnecting);
|
||||||
|
NetworkStatusIcon.Rotation = 0;
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Cog, Brushes.DimGray);
|
||||||
|
NetworkStatusIcon.Spin = true;
|
||||||
|
NetworkStatusIcon.SpinDuration = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkDisconnected);
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Ban, Brushes.DarkOrange);
|
||||||
|
NetworkStatusIcon.Spin = false;
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateText(string text)
|
private UIElement GetWirelessIcon(int signalStrength)
|
||||||
{
|
|
||||||
Button.ToolTip = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UIElement GetIcon(int signalStrength)
|
|
||||||
{
|
{
|
||||||
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
|
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
|
||||||
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/WiFi_{icon}.xaml");
|
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Desktop;component/Images/WiFi_{icon}.xaml");
|
|
@ -109,11 +109,11 @@
|
||||||
<Compile Include="Controls\ActionCenter\QuitButton.xaml.cs">
|
<Compile Include="Controls\ActionCenter\QuitButton.xaml.cs">
|
||||||
<DependentUpon>QuitButton.xaml</DependentUpon>
|
<DependentUpon>QuitButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\ActionCenter\WirelessNetworkButton.xaml.cs">
|
<Compile Include="Controls\ActionCenter\NetworkButton.xaml.cs">
|
||||||
<DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
|
<DependentUpon>NetworkButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\ActionCenter\WirelessNetworkControl.xaml.cs">
|
<Compile Include="Controls\ActionCenter\NetworkControl.xaml.cs">
|
||||||
<DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
|
<DependentUpon>NetworkControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\Browser\DownloadItemControl.xaml.cs">
|
<Compile Include="Controls\Browser\DownloadItemControl.xaml.cs">
|
||||||
<DependentUpon>DownloadItemControl.xaml</DependentUpon>
|
<DependentUpon>DownloadItemControl.xaml</DependentUpon>
|
||||||
|
@ -145,11 +145,11 @@
|
||||||
<Compile Include="Controls\Taskbar\QuitButton.xaml.cs">
|
<Compile Include="Controls\Taskbar\QuitButton.xaml.cs">
|
||||||
<DependentUpon>QuitButton.xaml</DependentUpon>
|
<DependentUpon>QuitButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\Taskbar\WirelessNetworkButton.xaml.cs">
|
<Compile Include="Controls\Taskbar\NetworkButton.xaml.cs">
|
||||||
<DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
|
<DependentUpon>NetworkButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\Taskbar\WirelessNetworkControl.xaml.cs">
|
<Compile Include="Controls\Taskbar\NetworkControl.xaml.cs">
|
||||||
<DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
|
<DependentUpon>NetworkControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\Taskview\WindowControl.xaml.cs">
|
<Compile Include="Controls\Taskview\WindowControl.xaml.cs">
|
||||||
<DependentUpon>WindowControl.xaml</DependentUpon>
|
<DependentUpon>WindowControl.xaml</DependentUpon>
|
||||||
|
@ -263,11 +263,11 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Controls\ActionCenter\WirelessNetworkButton.xaml">
|
<Page Include="Controls\ActionCenter\NetworkButton.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Controls\ActionCenter\WirelessNetworkControl.xaml">
|
<Page Include="Controls\ActionCenter\NetworkControl.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
@ -451,11 +451,11 @@
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Resource>
|
</Resource>
|
||||||
<Page Include="Controls\Taskbar\WirelessNetworkButton.xaml">
|
<Page Include="Controls\Taskbar\NetworkButton.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Controls\Taskbar\WirelessNetworkControl.xaml">
|
<Page Include="Controls\Taskbar\NetworkControl.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
@ -22,8 +22,8 @@ using SafeExamBrowser.Settings.Browser;
|
||||||
using SafeExamBrowser.Settings.Proctoring;
|
using SafeExamBrowser.Settings.Proctoring;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
|
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
|
||||||
|
@ -37,7 +37,7 @@ namespace SafeExamBrowser.UserInterface.Desktop
|
||||||
{
|
{
|
||||||
public class UserInterfaceFactory : IUserInterfaceFactory
|
public class UserInterfaceFactory : IUserInterfaceFactory
|
||||||
{
|
{
|
||||||
private IText text;
|
private readonly IText text;
|
||||||
|
|
||||||
public UserInterfaceFactory(IText text)
|
public UserInterfaceFactory(IText text)
|
||||||
{
|
{
|
||||||
|
@ -131,6 +131,18 @@ namespace SafeExamBrowser.UserInterface.Desktop
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ISystemControl CreateNetworkControl(INetworkAdapter adapter, Location location)
|
||||||
|
{
|
||||||
|
if (location == Location.ActionCenter)
|
||||||
|
{
|
||||||
|
return new Controls.ActionCenter.NetworkControl(adapter, text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Controls.Taskbar.NetworkControl(adapter, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public INotificationControl CreateNotificationControl(INotification notification, Location location)
|
public INotificationControl CreateNotificationControl(INotification notification, Location location)
|
||||||
{
|
{
|
||||||
if (location == Location.ActionCenter)
|
if (location == Location.ActionCenter)
|
||||||
|
@ -226,18 +238,6 @@ namespace SafeExamBrowser.UserInterface.Desktop
|
||||||
return new Taskview();
|
return new Taskview();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISystemControl CreateWirelessNetworkControl(IWirelessAdapter wirelessAdapter, Location location)
|
|
||||||
{
|
|
||||||
if (location == Location.ActionCenter)
|
|
||||||
{
|
|
||||||
return new Controls.ActionCenter.WirelessNetworkControl(wirelessAdapter, text);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new Controls.Taskbar.WirelessNetworkControl(wirelessAdapter, text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeFontAwesome()
|
private void InitializeFontAwesome()
|
||||||
{
|
{
|
||||||
// To be able to use FontAwesome in XAML icon resources, we need to make sure that the FontAwesome.WPF assembly is loaded into
|
// To be able to use FontAwesome in XAML icon resources, we need to make sure that the FontAwesome.WPF assembly is loaded into
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter.WirelessNetworkButton" x:ClassModifier="internal"
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter.NetworkButton" x:ClassModifier="internal"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
@ -9,17 +9,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
|
namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
|
||||||
{
|
{
|
||||||
internal partial class WirelessNetworkButton : UserControl
|
internal partial class NetworkButton : UserControl
|
||||||
{
|
{
|
||||||
private IWirelessNetwork network;
|
private readonly IWirelessNetwork network;
|
||||||
|
|
||||||
internal event EventHandler NetworkSelected;
|
internal event EventHandler NetworkSelected;
|
||||||
|
|
||||||
internal WirelessNetworkButton(IWirelessNetwork network)
|
internal NetworkButton(IWirelessNetwork network)
|
||||||
{
|
{
|
||||||
this.network = network;
|
this.network = network;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
|
||||||
private void InitializeNetworkButton()
|
private void InitializeNetworkButton()
|
||||||
{
|
{
|
||||||
Button.Click += (o, args) => NetworkSelected?.Invoke(this, EventArgs.Empty);
|
Button.Click += (o, args) => NetworkSelected?.Invoke(this, EventArgs.Empty);
|
||||||
IsCurrentTextBlock.Visibility = network.Status == WirelessNetworkStatus.Connected ? Visibility.Visible : Visibility.Hidden;
|
IsCurrentTextBlock.Visibility = network.Status == ConnectionStatus.Connected ? Visibility.Visible : Visibility.Hidden;
|
||||||
NetworkNameTextBlock.Text = network.Name;
|
NetworkNameTextBlock.Text = network.Name;
|
||||||
SignalStrengthTextBlock.Text = $"{network.SignalStrength}%";
|
SignalStrengthTextBlock.Text = $"{network.SignalStrength}%";
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter.WirelessNetworkControl" x:ClassModifier="internal"
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter.NetworkControl" x:ClassModifier="internal"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<Popup x:Name="Popup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}">
|
<Popup x:Name="Popup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}">
|
||||||
<Border Background="Gray">
|
<Border Background="Gray">
|
||||||
<ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
<ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
||||||
<StackPanel x:Name="NetworksStackPanel" />
|
<StackPanel x:Name="WirelessNetworksStackPanel" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
|
@ -30,10 +30,11 @@
|
||||||
<RowDefinition Height="3*" />
|
<RowDefinition Height="3*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
|
<Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
<Viewbox x:Name="SignalStrengthIcon" Stretch="Uniform" Width="Auto" />
|
<Viewbox x:Name="WirelessIcon" Stretch="Uniform" Width="Auto" Visibility="Collapsed" />
|
||||||
<fa:ImageAwesome x:Name="NoAdapterIcon" Foreground="Red" Icon="Ban" Margin="1" Opacity="0.3" Visibility="Collapsed" />
|
<fa:ImageAwesome x:Name="WiredIcon" Icon="Tv" Margin="0,2,4,4" Visibility="Collapsed" />
|
||||||
<fa:ImageAwesome x:Name="LoadingIcon" Foreground="Black" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" />
|
<Border Background="White" CornerRadius="6" Height="14" HorizontalAlignment="Right" Margin="-3,0" Panel.ZIndex="10" VerticalAlignment="Bottom">
|
||||||
<Image x:Name="NetworkStatusIcon" Height="8" HorizontalAlignment="Right" Margin="-2,0" Panel.ZIndex="10" VerticalAlignment="Bottom" />
|
<fa:ImageAwesome x:Name="NetworkStatusIcon" />
|
||||||
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
<TextBlock Grid.Row="1" x:Name="Text" FontSize="15" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
|
<TextBlock Grid.Row="1" x:Name="Text" FontSize="15" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
|
||||||
</Grid>
|
</Grid>
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using FontAwesome.WPF;
|
||||||
|
using SafeExamBrowser.Core.Contracts.Resources.Icons;
|
||||||
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
|
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
|
||||||
|
{
|
||||||
|
internal partial class NetworkControl : UserControl, ISystemControl
|
||||||
|
{
|
||||||
|
private readonly INetworkAdapter adapter;
|
||||||
|
private readonly IText text;
|
||||||
|
|
||||||
|
internal NetworkControl(INetworkAdapter adapter, IText text)
|
||||||
|
{
|
||||||
|
this.adapter = adapter;
|
||||||
|
this.text = text;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
InitializeWirelessNetworkControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
Dispatcher.InvokeAsync(() => Popup.IsOpen = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeWirelessNetworkControl()
|
||||||
|
{
|
||||||
|
var originalBrush = Grid.Background;
|
||||||
|
|
||||||
|
adapter.Changed += () => Dispatcher.InvokeAsync(Update);
|
||||||
|
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
||||||
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
||||||
|
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
||||||
|
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
|
||||||
|
Popup.Closed += (o, args) => Grid.Background = originalBrush;
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(0);
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
WirelessNetworksStackPanel.Children.Clear();
|
||||||
|
|
||||||
|
foreach (var network in adapter.GetWirelessNetworks())
|
||||||
|
{
|
||||||
|
var button = new NetworkButton(network);
|
||||||
|
|
||||||
|
button.NetworkSelected += (o, args) => adapter.ConnectToWirelessNetwork(network.Id);
|
||||||
|
|
||||||
|
if (network.Status == ConnectionStatus.Connected)
|
||||||
|
{
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(network.SignalStrength);
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkWirelessConnected).Replace("%%NAME%%", network.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
WirelessNetworksStackPanel.Children.Add(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adapter.Type)
|
||||||
|
{
|
||||||
|
case ConnectionType.Wired:
|
||||||
|
Button.IsEnabled = false;
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkWiredConnected));
|
||||||
|
WiredIcon.Visibility = Visibility.Visible;
|
||||||
|
WirelessIcon.Visibility = Visibility.Collapsed;
|
||||||
|
break;
|
||||||
|
case ConnectionType.Wireless:
|
||||||
|
Button.IsEnabled = true;
|
||||||
|
WiredIcon.Visibility = Visibility.Collapsed;
|
||||||
|
WirelessIcon.Visibility = Visibility.Visible;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Button.IsEnabled = false;
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkNotAvailable));
|
||||||
|
WiredIcon.Visibility = Visibility.Visible;
|
||||||
|
WirelessIcon.Visibility = Visibility.Collapsed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adapter.Status)
|
||||||
|
{
|
||||||
|
case ConnectionStatus.Connected:
|
||||||
|
NetworkStatusIcon.Rotation = 0;
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Globe, Brushes.Green);
|
||||||
|
NetworkStatusIcon.Spin = false;
|
||||||
|
break;
|
||||||
|
case ConnectionStatus.Connecting:
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkWirelessConnecting));
|
||||||
|
NetworkStatusIcon.Rotation = 0;
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Cog, Brushes.DimGray);
|
||||||
|
NetworkStatusIcon.Spin = true;
|
||||||
|
NetworkStatusIcon.SpinDuration = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UpdateText(text.Get(TextKey.SystemControl_NetworkDisconnected));
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Ban, Brushes.DarkOrange);
|
||||||
|
NetworkStatusIcon.Spin = false;
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateText(string text)
|
||||||
|
{
|
||||||
|
Button.ToolTip = text;
|
||||||
|
Text.Text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UIElement GetWirelessIcon(int signalStrength)
|
||||||
|
{
|
||||||
|
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
|
||||||
|
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/WiFi_Light_{icon}.xaml");
|
||||||
|
var resource = new XamlIconResource { Uri = uri };
|
||||||
|
|
||||||
|
return IconResourceLoader.Load(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Media;
|
|
||||||
using FontAwesome.WPF;
|
|
||||||
using SafeExamBrowser.Core.Contracts.Resources.Icons;
|
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
|
||||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
|
|
||||||
{
|
|
||||||
internal partial class WirelessNetworkControl : UserControl, ISystemControl
|
|
||||||
{
|
|
||||||
private IWirelessAdapter wirelessAdapter;
|
|
||||||
private IText text;
|
|
||||||
|
|
||||||
internal WirelessNetworkControl(IWirelessAdapter wirelessAdapter, IText text)
|
|
||||||
{
|
|
||||||
this.wirelessAdapter = wirelessAdapter;
|
|
||||||
this.text = text;
|
|
||||||
|
|
||||||
InitializeComponent();
|
|
||||||
InitializeWirelessNetworkControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => Popup.IsOpen = false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeWirelessNetworkControl()
|
|
||||||
{
|
|
||||||
var originalBrush = Grid.Background;
|
|
||||||
|
|
||||||
SignalStrengthIcon.Child = GetIcon(0);
|
|
||||||
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
|
||||||
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
|
||||||
Popup.Opened += (o, args) => Grid.Background = Brushes.Gray;
|
|
||||||
Popup.Closed += (o, args) => Grid.Background = originalBrush;
|
|
||||||
|
|
||||||
if (wirelessAdapter.IsAvailable)
|
|
||||||
{
|
|
||||||
wirelessAdapter.NetworksChanged += WirelessAdapter_NetworksChanged;
|
|
||||||
wirelessAdapter.StatusChanged += WirelessAdapter_StatusChanged;
|
|
||||||
UpdateNetworks();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Button.IsEnabled = false;
|
|
||||||
NoAdapterIcon.Visibility = Visibility.Visible;
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessNotAvailable));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WirelessAdapter_NetworksChanged()
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(UpdateNetworks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WirelessAdapter_StatusChanged(WirelessNetworkStatus status)
|
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => UpdateStatus(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateNetworks()
|
|
||||||
{
|
|
||||||
var status = WirelessNetworkStatus.Disconnected;
|
|
||||||
|
|
||||||
NetworksStackPanel.Children.Clear();
|
|
||||||
|
|
||||||
foreach (var network in wirelessAdapter.GetNetworks())
|
|
||||||
{
|
|
||||||
var button = new WirelessNetworkButton(network);
|
|
||||||
|
|
||||||
button.NetworkSelected += (o, args) => wirelessAdapter.Connect(network.Id);
|
|
||||||
|
|
||||||
if (network.Status == WirelessNetworkStatus.Connected)
|
|
||||||
{
|
|
||||||
status = WirelessNetworkStatus.Connected;
|
|
||||||
SignalStrengthIcon.Child = GetIcon(network.SignalStrength);
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", network.Name));
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworksStackPanel.Children.Add(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateStatus(WirelessNetworkStatus status)
|
|
||||||
{
|
|
||||||
LoadingIcon.Visibility = Visibility.Collapsed;
|
|
||||||
SignalStrengthIcon.Visibility = Visibility.Visible;
|
|
||||||
NetworkStatusIcon.Visibility = Visibility.Visible;
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case WirelessNetworkStatus.Connected:
|
|
||||||
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Check, Brushes.Green);
|
|
||||||
break;
|
|
||||||
case WirelessNetworkStatus.Connecting:
|
|
||||||
LoadingIcon.Visibility = Visibility.Visible;
|
|
||||||
SignalStrengthIcon.Visibility = Visibility.Collapsed;
|
|
||||||
NetworkStatusIcon.Visibility = Visibility.Collapsed;
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessConnecting));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Close, Brushes.Orange);
|
|
||||||
SignalStrengthIcon.Child = GetIcon(0);
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessDisconnected));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateText(string text)
|
|
||||||
{
|
|
||||||
Button.ToolTip = text;
|
|
||||||
Text.Text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UIElement GetIcon(int signalStrength)
|
|
||||||
{
|
|
||||||
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
|
|
||||||
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/WiFi_Light_{icon}.xaml");
|
|
||||||
var resource = new XamlIconResource { Uri = uri };
|
|
||||||
|
|
||||||
return IconResourceLoader.Load(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar.WirelessNetworkButton" x:ClassModifier="internal"
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar.NetworkButton" x:ClassModifier="internal"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
@ -9,17 +9,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
|
namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
|
||||||
{
|
{
|
||||||
internal partial class WirelessNetworkButton : UserControl
|
internal partial class NetworkButton : UserControl
|
||||||
{
|
{
|
||||||
private IWirelessNetwork network;
|
private readonly IWirelessNetwork network;
|
||||||
|
|
||||||
internal event EventHandler NetworkSelected;
|
internal event EventHandler NetworkSelected;
|
||||||
|
|
||||||
internal WirelessNetworkButton(IWirelessNetwork network)
|
internal NetworkButton(IWirelessNetwork network)
|
||||||
{
|
{
|
||||||
this.network = network;
|
this.network = network;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
|
||||||
private void InitializeNetworkButton()
|
private void InitializeNetworkButton()
|
||||||
{
|
{
|
||||||
Button.Click += (o, args) => NetworkSelected?.Invoke(this, EventArgs.Empty);
|
Button.Click += (o, args) => NetworkSelected?.Invoke(this, EventArgs.Empty);
|
||||||
IsCurrentTextBlock.Visibility = network.Status == WirelessNetworkStatus.Connected ? Visibility.Visible : Visibility.Hidden;
|
IsCurrentTextBlock.Visibility = network.Status == ConnectionStatus.Connected ? Visibility.Visible : Visibility.Hidden;
|
||||||
NetworkNameTextBlock.Text = network.Name;
|
NetworkNameTextBlock.Text = network.Name;
|
||||||
SignalStrengthTextBlock.Text = $"{network.SignalStrength}%";
|
SignalStrengthTextBlock.Text = $"{network.SignalStrength}%";
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar.WirelessNetworkControl" x:ClassModifier="internal"
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar.NetworkControl" x:ClassModifier="internal"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
@ -20,16 +20,17 @@
|
||||||
<Popup x:Name="Popup" IsOpen="False" Placement="Custom" PlacementTarget="{Binding ElementName=Button}">
|
<Popup x:Name="Popup" IsOpen="False" Placement="Custom" PlacementTarget="{Binding ElementName=Button}">
|
||||||
<Border Background="LightGray" BorderBrush="Gray" BorderThickness="1,1,1,0">
|
<Border Background="LightGray" BorderBrush="Gray" BorderThickness="1,1,1,0">
|
||||||
<ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
<ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
||||||
<StackPanel x:Name="NetworksStackPanel" />
|
<StackPanel x:Name="WirelessNetworksStackPanel" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
<Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="60">
|
<Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="60">
|
||||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
<Viewbox x:Name="SignalStrengthIcon" Stretch="Uniform" Width="Auto" />
|
<Viewbox x:Name="WirelessIcon" Stretch="Uniform" Width="Auto" Visibility="Collapsed" />
|
||||||
<fa:ImageAwesome x:Name="NoAdapterIcon" Foreground="Red" Icon="Ban" Margin="1" Opacity="0.3" Visibility="Collapsed" />
|
<fa:ImageAwesome x:Name="WiredIcon" Icon="Tv" Margin="0,2,4,4" Visibility="Collapsed" />
|
||||||
<fa:ImageAwesome x:Name="LoadingIcon" Foreground="Gray" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" />
|
<Border Background="{StaticResource BackgroundBrush}" CornerRadius="6" Height="18" HorizontalAlignment="Right" Margin="0,0,-1,1" Panel.ZIndex="10" VerticalAlignment="Bottom">
|
||||||
<Image x:Name="NetworkStatusIcon" Height="12" HorizontalAlignment="Right" Margin="0,2" Panel.ZIndex="10" VerticalAlignment="Bottom" />
|
<fa:ImageAwesome x:Name="NetworkStatusIcon" />
|
||||||
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
|
@ -15,20 +15,20 @@ using System.Windows.Media;
|
||||||
using FontAwesome.WPF;
|
using FontAwesome.WPF;
|
||||||
using SafeExamBrowser.Core.Contracts.Resources.Icons;
|
using SafeExamBrowser.Core.Contracts.Resources.Icons;
|
||||||
using SafeExamBrowser.I18n.Contracts;
|
using SafeExamBrowser.I18n.Contracts;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
using SafeExamBrowser.UserInterface.Shared.Utilities;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
|
namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
|
||||||
{
|
{
|
||||||
internal partial class WirelessNetworkControl : UserControl, ISystemControl
|
internal partial class NetworkControl : UserControl, ISystemControl
|
||||||
{
|
{
|
||||||
private IWirelessAdapter wirelessAdapter;
|
private readonly INetworkAdapter adapter;
|
||||||
private IText text;
|
private readonly IText text;
|
||||||
|
|
||||||
internal WirelessNetworkControl(IWirelessAdapter wirelessAdapter, IText text)
|
internal NetworkControl(INetworkAdapter adapter, IText text)
|
||||||
{
|
{
|
||||||
this.wirelessAdapter = wirelessAdapter;
|
this.adapter = adapter;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -44,11 +44,12 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
|
||||||
{
|
{
|
||||||
var originalBrush = Button.Background;
|
var originalBrush = Button.Background;
|
||||||
|
|
||||||
SignalStrengthIcon.Child = GetIcon(0);
|
adapter.Changed += () => Dispatcher.InvokeAsync(Update);
|
||||||
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
||||||
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
Button.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = Popup.IsMouseOver));
|
||||||
Popup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
|
Popup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
|
||||||
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(0);
|
||||||
|
|
||||||
Popup.Opened += (o, args) =>
|
Popup.Opened += (o, args) =>
|
||||||
{
|
{
|
||||||
|
@ -62,18 +63,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
|
||||||
Button.Background = originalBrush;
|
Button.Background = originalBrush;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (wirelessAdapter.IsAvailable)
|
Update();
|
||||||
{
|
|
||||||
wirelessAdapter.NetworksChanged += WirelessAdapter_NetworksChanged;
|
|
||||||
wirelessAdapter.StatusChanged += WirelessAdapter_StatusChanged;
|
|
||||||
UpdateNetworks();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Button.IsEnabled = false;
|
|
||||||
NoAdapterIcon.Visibility = Visibility.Visible;
|
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessNotAvailable));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CustomPopupPlacement[] Popup_PlacementCallback(Size popupSize, Size targetSize, Point offset)
|
private CustomPopupPlacement[] Popup_PlacementCallback(Size popupSize, Size targetSize, Point offset)
|
||||||
|
@ -84,72 +74,70 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WirelessAdapter_NetworksChanged()
|
private void Update()
|
||||||
{
|
{
|
||||||
Dispatcher.InvokeAsync(UpdateNetworks);
|
WirelessNetworksStackPanel.Children.Clear();
|
||||||
}
|
|
||||||
|
|
||||||
private void WirelessAdapter_StatusChanged(WirelessNetworkStatus status)
|
foreach (var network in adapter.GetWirelessNetworks())
|
||||||
{
|
|
||||||
Dispatcher.InvokeAsync(() => UpdateStatus(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateNetworks()
|
|
||||||
{
|
|
||||||
var status = WirelessNetworkStatus.Disconnected;
|
|
||||||
|
|
||||||
NetworksStackPanel.Children.Clear();
|
|
||||||
|
|
||||||
foreach (var network in wirelessAdapter.GetNetworks())
|
|
||||||
{
|
{
|
||||||
var button = new WirelessNetworkButton(network);
|
var button = new NetworkButton(network);
|
||||||
|
|
||||||
button.NetworkSelected += (o, args) => wirelessAdapter.Connect(network.Id);
|
button.NetworkSelected += (o, args) => adapter.ConnectToWirelessNetwork(network.Id);
|
||||||
|
|
||||||
if (network.Status == WirelessNetworkStatus.Connected)
|
if (network.Status == ConnectionStatus.Connected)
|
||||||
{
|
{
|
||||||
status = WirelessNetworkStatus.Connected;
|
WirelessIcon.Child = GetWirelessIcon(network.SignalStrength);
|
||||||
SignalStrengthIcon.Child = GetIcon(network.SignalStrength);
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWirelessConnected).Replace("%%NAME%%", network.Name);
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", network.Name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworksStackPanel.Children.Add(button);
|
WirelessNetworksStackPanel.Children.Add(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateStatus(status);
|
switch (adapter.Type)
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateStatus(WirelessNetworkStatus status)
|
|
||||||
{
|
|
||||||
LoadingIcon.Visibility = Visibility.Collapsed;
|
|
||||||
SignalStrengthIcon.Visibility = Visibility.Visible;
|
|
||||||
NetworkStatusIcon.Visibility = Visibility.Visible;
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
{
|
||||||
case WirelessNetworkStatus.Connected:
|
case ConnectionType.Wired:
|
||||||
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Check, Brushes.Green);
|
Button.IsEnabled = false;
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWiredConnected);
|
||||||
|
WiredIcon.Visibility = Visibility.Visible;
|
||||||
|
WirelessIcon.Visibility = Visibility.Collapsed;
|
||||||
break;
|
break;
|
||||||
case WirelessNetworkStatus.Connecting:
|
case ConnectionType.Wireless:
|
||||||
LoadingIcon.Visibility = Visibility.Visible;
|
Button.IsEnabled = true;
|
||||||
SignalStrengthIcon.Visibility = Visibility.Collapsed;
|
WiredIcon.Visibility = Visibility.Collapsed;
|
||||||
NetworkStatusIcon.Visibility = Visibility.Collapsed;
|
WirelessIcon.Visibility = Visibility.Visible;
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessConnecting));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Close, Brushes.Orange);
|
Button.IsEnabled = false;
|
||||||
SignalStrengthIcon.Child = GetIcon(0);
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkNotAvailable);
|
||||||
UpdateText(text.Get(TextKey.SystemControl_WirelessDisconnected));
|
WiredIcon.Visibility = Visibility.Visible;
|
||||||
|
WirelessIcon.Visibility = Visibility.Collapsed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adapter.Status)
|
||||||
|
{
|
||||||
|
case ConnectionStatus.Connected:
|
||||||
|
NetworkStatusIcon.Rotation = 0;
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Globe, Brushes.Green);
|
||||||
|
NetworkStatusIcon.Spin = false;
|
||||||
|
break;
|
||||||
|
case ConnectionStatus.Connecting:
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWirelessConnecting);
|
||||||
|
NetworkStatusIcon.Rotation = 0;
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Cog, Brushes.DimGray);
|
||||||
|
NetworkStatusIcon.Spin = true;
|
||||||
|
NetworkStatusIcon.SpinDuration = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Button.ToolTip = text.Get(TextKey.SystemControl_NetworkDisconnected);
|
||||||
|
NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Ban, Brushes.DarkOrange);
|
||||||
|
NetworkStatusIcon.Spin = false;
|
||||||
|
WirelessIcon.Child = GetWirelessIcon(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateText(string text)
|
private UIElement GetWirelessIcon(int signalStrength)
|
||||||
{
|
|
||||||
Button.ToolTip = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UIElement GetIcon(int signalStrength)
|
|
||||||
{
|
{
|
||||||
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
|
var icon = signalStrength > 66 ? "100" : (signalStrength > 33 ? "66" : (signalStrength > 0 ? "33" : "0"));
|
||||||
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/WiFi_{icon}.xaml");
|
var uri = new Uri($"pack://application:,,,/SafeExamBrowser.UserInterface.Mobile;component/Images/WiFi_{icon}.xaml");
|
|
@ -110,11 +110,11 @@
|
||||||
<Compile Include="Controls\ActionCenter\QuitButton.xaml.cs">
|
<Compile Include="Controls\ActionCenter\QuitButton.xaml.cs">
|
||||||
<DependentUpon>QuitButton.xaml</DependentUpon>
|
<DependentUpon>QuitButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\ActionCenter\WirelessNetworkButton.xaml.cs">
|
<Compile Include="Controls\ActionCenter\NetworkButton.xaml.cs">
|
||||||
<DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
|
<DependentUpon>NetworkButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\ActionCenter\WirelessNetworkControl.xaml.cs">
|
<Compile Include="Controls\ActionCenter\NetworkControl.xaml.cs">
|
||||||
<DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
|
<DependentUpon>NetworkControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\Browser\DownloadItemControl.xaml.cs">
|
<Compile Include="Controls\Browser\DownloadItemControl.xaml.cs">
|
||||||
<DependentUpon>DownloadItemControl.xaml</DependentUpon>
|
<DependentUpon>DownloadItemControl.xaml</DependentUpon>
|
||||||
|
@ -146,11 +146,11 @@
|
||||||
<Compile Include="Controls\Taskbar\QuitButton.xaml.cs">
|
<Compile Include="Controls\Taskbar\QuitButton.xaml.cs">
|
||||||
<DependentUpon>QuitButton.xaml</DependentUpon>
|
<DependentUpon>QuitButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\Taskbar\WirelessNetworkButton.xaml.cs">
|
<Compile Include="Controls\Taskbar\NetworkButton.xaml.cs">
|
||||||
<DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
|
<DependentUpon>NetworkButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\Taskbar\WirelessNetworkControl.xaml.cs">
|
<Compile Include="Controls\Taskbar\NetworkControl.xaml.cs">
|
||||||
<DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
|
<DependentUpon>NetworkControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\Taskview\WindowControl.xaml.cs">
|
<Compile Include="Controls\Taskview\WindowControl.xaml.cs">
|
||||||
<DependentUpon>WindowControl.xaml</DependentUpon>
|
<DependentUpon>WindowControl.xaml</DependentUpon>
|
||||||
|
@ -321,11 +321,11 @@
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Controls\ActionCenter\WirelessNetworkButton.xaml">
|
<Page Include="Controls\ActionCenter\NetworkButton.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Controls\ActionCenter\WirelessNetworkControl.xaml">
|
<Page Include="Controls\ActionCenter\NetworkControl.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
@ -369,11 +369,11 @@
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Controls\Taskbar\WirelessNetworkButton.xaml">
|
<Page Include="Controls\Taskbar\NetworkButton.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Controls\Taskbar\WirelessNetworkControl.xaml">
|
<Page Include="Controls\Taskbar\NetworkControl.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
@ -22,8 +22,8 @@ using SafeExamBrowser.Settings.Browser;
|
||||||
using SafeExamBrowser.Settings.Proctoring;
|
using SafeExamBrowser.Settings.Proctoring;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
|
|
||||||
using SafeExamBrowser.UserInterface.Contracts;
|
using SafeExamBrowser.UserInterface.Contracts;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
|
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
|
||||||
|
@ -37,7 +37,7 @@ namespace SafeExamBrowser.UserInterface.Mobile
|
||||||
{
|
{
|
||||||
public class UserInterfaceFactory : IUserInterfaceFactory
|
public class UserInterfaceFactory : IUserInterfaceFactory
|
||||||
{
|
{
|
||||||
private IText text;
|
private readonly IText text;
|
||||||
|
|
||||||
public UserInterfaceFactory(IText text)
|
public UserInterfaceFactory(IText text)
|
||||||
{
|
{
|
||||||
|
@ -131,6 +131,18 @@ namespace SafeExamBrowser.UserInterface.Mobile
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ISystemControl CreateNetworkControl(INetworkAdapter adapter, Location location)
|
||||||
|
{
|
||||||
|
if (location == Location.ActionCenter)
|
||||||
|
{
|
||||||
|
return new Controls.ActionCenter.NetworkControl(adapter, text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Controls.Taskbar.NetworkControl(adapter, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public INotificationControl CreateNotificationControl(INotification notification, Location location)
|
public INotificationControl CreateNotificationControl(INotification notification, Location location)
|
||||||
{
|
{
|
||||||
if (location == Location.ActionCenter)
|
if (location == Location.ActionCenter)
|
||||||
|
@ -226,18 +238,6 @@ namespace SafeExamBrowser.UserInterface.Mobile
|
||||||
return new Taskview();
|
return new Taskview();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISystemControl CreateWirelessNetworkControl(IWirelessAdapter wirelessAdapter, Location location)
|
|
||||||
{
|
|
||||||
if (location == Location.ActionCenter)
|
|
||||||
{
|
|
||||||
return new Controls.ActionCenter.WirelessNetworkControl(wirelessAdapter, text);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new Controls.Taskbar.WirelessNetworkControl(wirelessAdapter, text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeFontAwesome()
|
private void InitializeFontAwesome()
|
||||||
{
|
{
|
||||||
// To be able to use FontAwesome in XAML icon resources, we need to make sure that the FontAwesome.WPF assembly is loaded into
|
// To be able to use FontAwesome in XAML icon resources, we need to make sure that the FontAwesome.WPF assembly is loaded into
|
||||||
|
|
|
@ -108,6 +108,11 @@ namespace SafeExamBrowser.WindowsApi.Contracts
|
||||||
/// </exception>
|
/// </exception>
|
||||||
IBounds GetWorkingArea();
|
IBounds GetWorkingArea();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether this computer is connected to the internet. Returns <c>true</c> if successful, otherwise <c>false</c>.
|
||||||
|
/// </summary>
|
||||||
|
bool HasInternetConnection();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hides the given window. Returns <c>true</c> if successful, otherwise <c>false</c>.
|
/// Hides the given window. Returns <c>true</c> if successful, otherwise <c>false</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -24,9 +24,9 @@ namespace SafeExamBrowser.WindowsApi
|
||||||
{
|
{
|
||||||
public class NativeMethods : INativeMethods
|
public class NativeMethods : INativeMethods
|
||||||
{
|
{
|
||||||
private ConcurrentDictionary<Guid, KeyboardHook> KeyboardHooks = new ConcurrentDictionary<Guid, KeyboardHook>();
|
private readonly ConcurrentDictionary<Guid, KeyboardHook> KeyboardHooks = new ConcurrentDictionary<Guid, KeyboardHook>();
|
||||||
private ConcurrentDictionary<Guid, MouseHook> MouseHooks = new ConcurrentDictionary<Guid, MouseHook>();
|
private readonly ConcurrentDictionary<Guid, MouseHook> MouseHooks = new ConcurrentDictionary<Guid, MouseHook>();
|
||||||
private ConcurrentDictionary<Guid, SystemHook> SystemHooks = new ConcurrentDictionary<Guid, SystemHook>();
|
private readonly ConcurrentDictionary<Guid, SystemHook> SystemHooks = new ConcurrentDictionary<Guid, SystemHook>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Upon finalization, unregister all active system events and hooks...
|
/// Upon finalization, unregister all active system events and hooks...
|
||||||
|
@ -245,6 +245,11 @@ namespace SafeExamBrowser.WindowsApi
|
||||||
return workingArea.ToBounds();
|
return workingArea.ToBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasInternetConnection()
|
||||||
|
{
|
||||||
|
return WinInet.InternetGetConnectedState(out _, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public bool HideWindow(IntPtr window)
|
public bool HideWindow(IntPtr window)
|
||||||
{
|
{
|
||||||
return User32.ShowWindow(window, (int) ShowWindowCommand.Hide);
|
return User32.ShowWindow(window, (int) ShowWindowCommand.Hide);
|
||||||
|
|
|
@ -92,6 +92,7 @@
|
||||||
<Compile Include="Types\Window.cs" />
|
<Compile Include="Types\Window.cs" />
|
||||||
<Compile Include="Types\WINDOWPLACEMENT.cs" />
|
<Compile Include="Types\WINDOWPLACEMENT.cs" />
|
||||||
<Compile Include="User32.cs" />
|
<Compile Include="User32.cs" />
|
||||||
|
<Compile Include="WinInet.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
|
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
|
||||||
|
|
21
SafeExamBrowser.WindowsApi/WinInet.cs
Normal file
21
SafeExamBrowser.WindowsApi/WinInet.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.WindowsApi
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides access to the native Windows API exposed by <c>wininet.dll</c>.
|
||||||
|
/// </summary>
|
||||||
|
internal static class WinInet
|
||||||
|
{
|
||||||
|
[DllImport("wininet.dll", SetLastError = true)]
|
||||||
|
internal static extern bool InternetGetConnectedState(out int description, int reservedValue);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue