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.Audio;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
			
		|||
		private Mock<ITaskview> taskview;
 | 
			
		||||
		private Mock<IText> text;
 | 
			
		||||
		private Mock<IUserInterfaceFactory> uiFactory;
 | 
			
		||||
		private Mock<IWirelessAdapter> wirelessAdapter;
 | 
			
		||||
		private Mock<INetworkAdapter> networkAdapter;
 | 
			
		||||
 | 
			
		||||
		private ShellOperation sut;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,13 +55,13 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
			
		|||
			aboutNotification = new Mock<INotification>();
 | 
			
		||||
			keyboard = new Mock<IKeyboard>();
 | 
			
		||||
			logNotification = new Mock<INotification>();
 | 
			
		||||
			networkAdapter = new Mock<INetworkAdapter>();
 | 
			
		||||
			powerSupply = new Mock<IPowerSupply>();
 | 
			
		||||
			systemInfo = new Mock<ISystemInfo>();
 | 
			
		||||
			taskbar = new Mock<ITaskbar>();
 | 
			
		||||
			taskview = new Mock<ITaskview>();
 | 
			
		||||
			text = new Mock<IText>();
 | 
			
		||||
			uiFactory = new Mock<IUserInterfaceFactory>();
 | 
			
		||||
			wirelessAdapter = new Mock<IWirelessAdapter>();
 | 
			
		||||
 | 
			
		||||
			context.Settings = new AppSettings();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -77,13 +77,13 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
			
		|||
				keyboard.Object,
 | 
			
		||||
				logger.Object,
 | 
			
		||||
				logNotification.Object,
 | 
			
		||||
				networkAdapter.Object,
 | 
			
		||||
				powerSupply.Object,
 | 
			
		||||
				systemInfo.Object,
 | 
			
		||||
				taskbar.Object,
 | 
			
		||||
				taskview.Object,
 | 
			
		||||
				text.Object,
 | 
			
		||||
				uiFactory.Object,
 | 
			
		||||
				wirelessAdapter.Object);
 | 
			
		||||
				uiFactory.Object);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[TestMethod]
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
			
		|||
			context.Settings.ActionCenter.EnableActionCenter = true;
 | 
			
		||||
			context.Settings.Keyboard.AllowAltTab = true;
 | 
			
		||||
			context.Settings.Security.AllowTermination = true;
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			sut.Perform();
 | 
			
		||||
 | 
			
		||||
			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.ShowAudio = true;
 | 
			
		||||
			context.Settings.ActionCenter.ShowKeyboardLayout = true;
 | 
			
		||||
			context.Settings.ActionCenter.ShowWirelessNetwork = true;
 | 
			
		||||
			context.Settings.ActionCenter.ShowNetwork = true;
 | 
			
		||||
			context.Settings.Taskbar.EnableTaskbar = true;
 | 
			
		||||
			context.Settings.Taskbar.ShowAudio = true;
 | 
			
		||||
			context.Settings.Taskbar.ShowKeyboardLayout = true;
 | 
			
		||||
			context.Settings.Taskbar.ShowWirelessNetwork = true;
 | 
			
		||||
			context.Settings.Taskbar.ShowNetwork = 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.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.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();
 | 
			
		||||
 | 
			
		||||
			audio.Verify(a => a.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);
 | 
			
		||||
			actionCenter.Verify(a => a.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.ShowAudio = false;
 | 
			
		||||
			context.Settings.ActionCenter.ShowKeyboardLayout = false;
 | 
			
		||||
			context.Settings.ActionCenter.ShowWirelessNetwork = false;
 | 
			
		||||
			context.Settings.ActionCenter.ShowNetwork = false;
 | 
			
		||||
			context.Settings.Taskbar.EnableTaskbar = true;
 | 
			
		||||
			context.Settings.Taskbar.ShowAudio = false;
 | 
			
		||||
			context.Settings.Taskbar.ShowKeyboardLayout = false;
 | 
			
		||||
			context.Settings.Taskbar.ShowWirelessNetwork = false;
 | 
			
		||||
			context.Settings.Taskbar.ShowNetwork = 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.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.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();
 | 
			
		||||
 | 
			
		||||
			audio.Verify(a => a.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);
 | 
			
		||||
			actionCenter.Verify(a => a.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);
 | 
			
		||||
			powerSupply.Verify(p => p.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.Audio;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Keyboard;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Network;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.PowerSupply;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.FileSystemDialog;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +71,7 @@ namespace SafeExamBrowser.Client
 | 
			
		|||
		private ILogger logger;
 | 
			
		||||
		private IMessageBox messageBox;
 | 
			
		||||
		private INativeMethods nativeMethods;
 | 
			
		||||
		private INetworkAdapter networkAdapter;
 | 
			
		||||
		private IPowerSupply powerSupply;
 | 
			
		||||
		private IRuntimeProxy runtimeProxy;
 | 
			
		||||
		private ISystemInfo systemInfo;
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +80,6 @@ namespace SafeExamBrowser.Client
 | 
			
		|||
		private IUserInfo userInfo;
 | 
			
		||||
		private IText text;
 | 
			
		||||
		private IUserInterfaceFactory uiFactory;
 | 
			
		||||
		private IWirelessAdapter wirelessAdapter;
 | 
			
		||||
 | 
			
		||||
		internal ClientController ClientController { get; private set; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -96,13 +96,13 @@ namespace SafeExamBrowser.Client
 | 
			
		|||
			context = new ClientContext();
 | 
			
		||||
			messageBox = BuildMessageBox();
 | 
			
		||||
			nativeMethods = new NativeMethods();
 | 
			
		||||
			networkAdapter = new NetworkAdapter(ModuleLogger(nameof(NetworkAdapter)), nativeMethods);
 | 
			
		||||
			powerSupply = new PowerSupply(ModuleLogger(nameof(PowerSupply)));
 | 
			
		||||
			runtimeProxy = new RuntimeProxy(runtimeHostUri, new ProxyObjectFactory(), ModuleLogger(nameof(RuntimeProxy)), Interlocutor.Client);
 | 
			
		||||
			systemInfo = new SystemInfo();
 | 
			
		||||
			taskbar = uiFactory.CreateTaskbar(ModuleLogger("Taskbar"));
 | 
			
		||||
			taskview = uiFactory.CreateTaskview();
 | 
			
		||||
			userInfo = new UserInfo(ModuleLogger(nameof(UserInfo)));
 | 
			
		||||
			wirelessAdapter = new WirelessAdapter(ModuleLogger(nameof(WirelessAdapter)));
 | 
			
		||||
 | 
			
		||||
			var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory)));
 | 
			
		||||
			var applicationMonitor = new ApplicationMonitor(TWO_SECONDS, ModuleLogger(nameof(ApplicationMonitor)), nativeMethods, processFactory);
 | 
			
		||||
| 
						 | 
				
			
			@ -157,13 +157,13 @@ namespace SafeExamBrowser.Client
 | 
			
		|||
 | 
			
		||||
		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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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()
 | 
			
		||||
| 
						 | 
				
			
			@ -271,7 +271,7 @@ namespace SafeExamBrowser.Client
 | 
			
		|||
 | 
			
		||||
		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);
 | 
			
		||||
 | 
			
		||||
			context.Server = server;
 | 
			
		||||
| 
						 | 
				
			
			@ -293,13 +293,13 @@ namespace SafeExamBrowser.Client
 | 
			
		|||
				keyboard,
 | 
			
		||||
				logger,
 | 
			
		||||
				logNotification,
 | 
			
		||||
				networkAdapter,
 | 
			
		||||
				powerSupply,
 | 
			
		||||
				systemInfo,
 | 
			
		||||
				taskbar,
 | 
			
		||||
				taskview,
 | 
			
		||||
				text,
 | 
			
		||||
				uiFactory,
 | 
			
		||||
				wirelessAdapter);
 | 
			
		||||
				uiFactory);
 | 
			
		||||
 | 
			
		||||
			context.Activators.Add(new ActionCenterKeyboardActivator(ModuleLogger(nameof(ActionCenterKeyboardActivator)), 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.Audio;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -24,19 +24,19 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
{
 | 
			
		||||
	internal class ShellOperation : ClientOperation
 | 
			
		||||
	{
 | 
			
		||||
		private IActionCenter actionCenter;
 | 
			
		||||
		private IAudio audio;
 | 
			
		||||
		private INotification aboutNotification;
 | 
			
		||||
		private IKeyboard keyboard;
 | 
			
		||||
		private ILogger logger;
 | 
			
		||||
		private INotification logNotification;
 | 
			
		||||
		private IPowerSupply powerSupply;
 | 
			
		||||
		private ISystemInfo systemInfo;
 | 
			
		||||
		private ITaskbar taskbar;
 | 
			
		||||
		private ITaskview taskview;
 | 
			
		||||
		private IText text;
 | 
			
		||||
		private IUserInterfaceFactory uiFactory;
 | 
			
		||||
		private IWirelessAdapter wirelessAdapter;
 | 
			
		||||
		private readonly IActionCenter actionCenter;
 | 
			
		||||
		private readonly IAudio audio;
 | 
			
		||||
		private readonly INotification aboutNotification;
 | 
			
		||||
		private readonly IKeyboard keyboard;
 | 
			
		||||
		private readonly ILogger logger;
 | 
			
		||||
		private readonly INotification logNotification;
 | 
			
		||||
		private readonly INetworkAdapter networkAdapter;
 | 
			
		||||
		private readonly IPowerSupply powerSupply;
 | 
			
		||||
		private readonly ISystemInfo systemInfo;
 | 
			
		||||
		private readonly ITaskbar taskbar;
 | 
			
		||||
		private readonly ITaskview taskview;
 | 
			
		||||
		private readonly IText text;
 | 
			
		||||
		private readonly IUserInterfaceFactory uiFactory;
 | 
			
		||||
 | 
			
		||||
		public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
 | 
			
		||||
		public override event StatusChangedEventHandler StatusChanged;
 | 
			
		||||
| 
						 | 
				
			
			@ -49,13 +49,13 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
			IKeyboard keyboard,
 | 
			
		||||
			ILogger logger,
 | 
			
		||||
			INotification logNotification,
 | 
			
		||||
			INetworkAdapter networkAdapter,
 | 
			
		||||
			IPowerSupply powerSupply,
 | 
			
		||||
			ISystemInfo systemInfo,
 | 
			
		||||
			ITaskbar taskbar,
 | 
			
		||||
			ITaskview taskview,
 | 
			
		||||
			IText text,
 | 
			
		||||
			IUserInterfaceFactory uiFactory,
 | 
			
		||||
			IWirelessAdapter wirelessAdapter) : base(context)
 | 
			
		||||
			IUserInterfaceFactory uiFactory) : base(context)
 | 
			
		||||
		{
 | 
			
		||||
			this.aboutNotification = aboutNotification;
 | 
			
		||||
			this.actionCenter = actionCenter;
 | 
			
		||||
| 
						 | 
				
			
			@ -63,13 +63,13 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
			this.keyboard = keyboard;
 | 
			
		||||
			this.logger = logger;
 | 
			
		||||
			this.logNotification = logNotification;
 | 
			
		||||
			this.networkAdapter = networkAdapter;
 | 
			
		||||
			this.powerSupply = powerSupply;
 | 
			
		||||
			this.systemInfo = systemInfo;
 | 
			
		||||
			this.text = text;
 | 
			
		||||
			this.taskbar = taskbar;
 | 
			
		||||
			this.taskview = taskview;
 | 
			
		||||
			this.uiFactory = uiFactory;
 | 
			
		||||
			this.wirelessAdapter = wirelessAdapter;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override OperationResult Perform()
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +134,7 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
				InitializeClockForActionCenter();
 | 
			
		||||
				InitializeLogNotificationForActionCenter();
 | 
			
		||||
				InitializeKeyboardLayoutForActionCenter();
 | 
			
		||||
				InitializeWirelessNetworkForActionCenter();
 | 
			
		||||
				InitializeNetworkForActionCenter();
 | 
			
		||||
				InitializePowerSupplyForActionCenter();
 | 
			
		||||
				InitializeQuitButtonForActionCenter();
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +155,7 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
				InitializeAboutNotificationForTaskbar();
 | 
			
		||||
				InitializeLogNotificationForTaskbar();
 | 
			
		||||
				InitializePowerSupplyForTaskbar();
 | 
			
		||||
				InitializeWirelessNetworkForTaskbar();
 | 
			
		||||
				InitializeNetworkForTaskbar();
 | 
			
		||||
				InitializeAudioForTaskbar();
 | 
			
		||||
				InitializeKeyboardLayoutForTaskbar();
 | 
			
		||||
				InitializeClockForTaskbar();
 | 
			
		||||
| 
						 | 
				
			
			@ -204,8 +204,8 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
		{
 | 
			
		||||
			audio.Initialize();
 | 
			
		||||
			keyboard.Initialize();
 | 
			
		||||
			networkAdapter.Initialize();
 | 
			
		||||
			powerSupply.Initialize();
 | 
			
		||||
			wirelessAdapter.Initialize();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void InitializeAboutNotificationForActionCenter()
 | 
			
		||||
| 
						 | 
				
			
			@ -308,19 +308,19 @@ namespace SafeExamBrowser.Client.Operations
 | 
			
		|||
			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();
 | 
			
		||||
			keyboard.Terminate();
 | 
			
		||||
			networkAdapter.Terminate();
 | 
			
		||||
			powerSupply.Terminate();
 | 
			
		||||
			wirelessAdapter.Terminate();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,6 @@ namespace SafeExamBrowser.Configuration.UnitTests
 | 
			
		|||
		private Mock<ICertificateStore> certificateStore;
 | 
			
		||||
		private Mock<IResourceLoader> fileLoader;
 | 
			
		||||
		private Mock<IResourceSaver> fileSaver;
 | 
			
		||||
		private Mock<IHashAlgorithm> hashAlgorithm;
 | 
			
		||||
		private Mock<IModuleLogger> logger;
 | 
			
		||||
		private Mock<IResourceLoader> networkLoader;
 | 
			
		||||
		private Mock<IDataParser> xmlParser;
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +43,6 @@ namespace SafeExamBrowser.Configuration.UnitTests
 | 
			
		|||
			certificateStore = new Mock<ICertificateStore>();
 | 
			
		||||
			fileLoader = new Mock<IResourceLoader>();
 | 
			
		||||
			fileSaver = new Mock<IResourceSaver>();
 | 
			
		||||
			hashAlgorithm = new Mock<IHashAlgorithm>();
 | 
			
		||||
			logger = new Mock<IModuleLogger>();
 | 
			
		||||
			networkLoader = new Mock<IResourceLoader>();
 | 
			
		||||
			xmlParser = new Mock<IDataParser>();
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +54,7 @@ namespace SafeExamBrowser.Configuration.UnitTests
 | 
			
		|||
 | 
			
		||||
			SetEntryAssembly();
 | 
			
		||||
 | 
			
		||||
			sut = new ConfigurationRepository(certificateStore.Object, hashAlgorithm.Object, logger.Object);
 | 
			
		||||
			sut = new ConfigurationRepository(certificateStore.Object, logger.Object);
 | 
			
		||||
			sut.InitializeAppConfig();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,8 +29,8 @@ namespace SafeExamBrowser.Configuration.ConfigurationData.DataMapping
 | 
			
		|||
				case Keys.UserInterface.ShowKeyboardLayout:
 | 
			
		||||
					MapShowKeyboardLayout(settings, value);
 | 
			
		||||
					break;
 | 
			
		||||
				case Keys.UserInterface.ShowWirelessNetwork:
 | 
			
		||||
					MapShowWirelessNetwork(settings, value);
 | 
			
		||||
				case Keys.UserInterface.ShowNetwork:
 | 
			
		||||
					MapShowNetwork(settings, value);
 | 
			
		||||
					break;
 | 
			
		||||
				case Keys.UserInterface.Taskbar.EnableTaskbar:
 | 
			
		||||
					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)
 | 
			
		||||
			{
 | 
			
		||||
				settings.ActionCenter.ShowWirelessNetwork = show;
 | 
			
		||||
				settings.Taskbar.ShowWirelessNetwork = show;
 | 
			
		||||
				settings.ActionCenter.ShowNetwork = show;
 | 
			
		||||
				settings.Taskbar.ShowNetwork = show;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -101,9 +101,9 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
 | 
			
		|||
			settings.ActionCenter.EnableActionCenter = true;
 | 
			
		||||
			settings.ActionCenter.ShowApplicationInfo = true;
 | 
			
		||||
			settings.ActionCenter.ShowApplicationLog = false;
 | 
			
		||||
			settings.ActionCenter.ShowKeyboardLayout = true;
 | 
			
		||||
			settings.ActionCenter.ShowWirelessNetwork = false;
 | 
			
		||||
			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 = "AeroAdmin.exe", OriginalName = "AeroAdmin.exe" });
 | 
			
		||||
| 
						 | 
				
			
			@ -283,12 +283,12 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
 | 
			
		|||
			settings.Taskbar.EnableTaskbar = true;
 | 
			
		||||
			settings.Taskbar.ShowApplicationInfo = false;
 | 
			
		||||
			settings.Taskbar.ShowApplicationLog = false;
 | 
			
		||||
			settings.Taskbar.ShowKeyboardLayout = true;
 | 
			
		||||
			settings.Taskbar.ShowWirelessNetwork = false;
 | 
			
		||||
			settings.Taskbar.ShowClock = true;
 | 
			
		||||
			settings.Taskbar.ShowKeyboardLayout = true;
 | 
			
		||||
			settings.Taskbar.ShowNetwork = false;
 | 
			
		||||
 | 
			
		||||
			settings.UserInterfaceMode = UserInterfaceMode.Desktop;
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			return settings;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -327,7 +327,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
 | 
			
		|||
			internal const string ShowAudio = "audioControlEnabled";
 | 
			
		||||
			internal const string ShowClock = "showTime";
 | 
			
		||||
			internal const string ShowKeyboardLayout = "showInputLanguage";
 | 
			
		||||
			internal const string ShowWirelessNetwork = "allowWlan";
 | 
			
		||||
			internal const string ShowNetwork = "allowWlan";
 | 
			
		||||
			internal const string UserInterfaceMode = "touchOptimized";
 | 
			
		||||
 | 
			
		||||
			internal static class ActionCenter
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,21 +22,19 @@ namespace SafeExamBrowser.Configuration
 | 
			
		|||
{
 | 
			
		||||
	public class ConfigurationRepository : IConfigurationRepository
 | 
			
		||||
	{
 | 
			
		||||
		private ICertificateStore certificateStore;
 | 
			
		||||
		private IList<IDataParser> dataParsers;
 | 
			
		||||
		private IList<IDataSerializer> dataSerializers;
 | 
			
		||||
		private DataMapper dataMapper;
 | 
			
		||||
		private DataProcessor dataProcessor;
 | 
			
		||||
		private DataValues dataValues;
 | 
			
		||||
		private IHashAlgorithm hashAlgorithm;
 | 
			
		||||
		private ILogger logger;
 | 
			
		||||
		private IList<IResourceLoader> resourceLoaders;
 | 
			
		||||
		private IList<IResourceSaver> resourceSavers;
 | 
			
		||||
		private readonly ICertificateStore certificateStore;
 | 
			
		||||
		private readonly IList<IDataParser> dataParsers;
 | 
			
		||||
		private readonly IList<IDataSerializer> dataSerializers;
 | 
			
		||||
		private readonly DataMapper dataMapper;
 | 
			
		||||
		private readonly DataProcessor dataProcessor;
 | 
			
		||||
		private readonly DataValues dataValues;
 | 
			
		||||
		private readonly ILogger logger;
 | 
			
		||||
		private readonly IList<IResourceLoader> resourceLoaders;
 | 
			
		||||
		private readonly IList<IResourceSaver> resourceSavers;
 | 
			
		||||
 | 
			
		||||
		public ConfigurationRepository(ICertificateStore certificateStore, IHashAlgorithm hashAlgorithm, IModuleLogger logger)
 | 
			
		||||
		public ConfigurationRepository(ICertificateStore certificateStore, IModuleLogger logger)
 | 
			
		||||
		{
 | 
			
		||||
			this.certificateStore = certificateStore;
 | 
			
		||||
			this.hashAlgorithm = hashAlgorithm;
 | 
			
		||||
			this.logger = logger;
 | 
			
		||||
 | 
			
		||||
			dataParsers = new List<IDataParser>();
 | 
			
		||||
| 
						 | 
				
			
			@ -171,7 +169,7 @@ namespace SafeExamBrowser.Configuration
 | 
			
		|||
			var status = LoadStatus.NotSupported;
 | 
			
		||||
			var resourceLoader = resourceLoaders.FirstOrDefault(l => l.CanLoad(resource));
 | 
			
		||||
 | 
			
		||||
			data = default(Stream);
 | 
			
		||||
			data = default;
 | 
			
		||||
 | 
			
		||||
			if (resourceLoader != null)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -191,8 +189,8 @@ namespace SafeExamBrowser.Configuration
 | 
			
		|||
			var parser = dataParsers.FirstOrDefault(p => p.CanParse(data));
 | 
			
		||||
			var status = LoadStatus.NotSupported;
 | 
			
		||||
 | 
			
		||||
			encryption = default(EncryptionParameters);
 | 
			
		||||
			format = default(FormatType);
 | 
			
		||||
			encryption = default;
 | 
			
		||||
			format = default;
 | 
			
		||||
			rawData = default(Dictionary<string, object>);
 | 
			
		||||
 | 
			
		||||
			if (parser != null)
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +235,7 @@ namespace SafeExamBrowser.Configuration
 | 
			
		|||
			var serializer = dataSerializers.FirstOrDefault(s => s.CanSerialize(format));
 | 
			
		||||
			var status = SaveStatus.NotSupported;
 | 
			
		||||
 | 
			
		||||
			serialized = default(Stream);
 | 
			
		||||
			serialized = default;
 | 
			
		||||
 | 
			
		||||
			if (serializer != null)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -213,10 +213,11 @@ namespace SafeExamBrowser.I18n.Contracts
 | 
			
		|||
		SystemControl_BatteryChargeLowInfo,
 | 
			
		||||
		SystemControl_BatteryRemainingCharge,
 | 
			
		||||
		SystemControl_KeyboardLayoutTooltip,
 | 
			
		||||
		SystemControl_WirelessConnected,
 | 
			
		||||
		SystemControl_WirelessConnecting,
 | 
			
		||||
		SystemControl_WirelessDisconnected,
 | 
			
		||||
		SystemControl_WirelessNotAvailable,
 | 
			
		||||
		SystemControl_NetworkDisconnected,
 | 
			
		||||
		SystemControl_NetworkNotAvailable,
 | 
			
		||||
		SystemControl_NetworkWiredConnected,
 | 
			
		||||
		SystemControl_NetworkWirelessConnected,
 | 
			
		||||
		SystemControl_NetworkWirelessConnecting,
 | 
			
		||||
		Version
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -597,17 +597,20 @@
 | 
			
		|||
    <Entry key="SystemControl_KeyboardLayoutTooltip">
 | 
			
		||||
        Das aktuelle Tastatur-Layout ist "%%LAYOUT%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnected">
 | 
			
		||||
        Verbunden mit "%%NAME%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnecting">
 | 
			
		||||
        Verbinde...
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessDisconnected">
 | 
			
		||||
    <Entry key="SystemControl_NetworkDisconnected">
 | 
			
		||||
        Getrennt
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessNotAvailable">
 | 
			
		||||
        Kein WLAN-Netzwerkadapter verfügbar oder eingestellt
 | 
			
		||||
    <Entry key="SystemControl_NetworkNotAvailable">
 | 
			
		||||
        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 key="Version">
 | 
			
		||||
        Version
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -597,18 +597,21 @@
 | 
			
		|||
    <Entry key="SystemControl_KeyboardLayoutTooltip">
 | 
			
		||||
        The current keyboard layout is "%%LAYOUT%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnected">
 | 
			
		||||
        Connected to "%%NAME%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnecting">
 | 
			
		||||
        Connecting...
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessDisconnected">
 | 
			
		||||
    <Entry key="SystemControl_NetworkDisconnected">
 | 
			
		||||
        Disconnected
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessNotAvailable">
 | 
			
		||||
    <Entry key="SystemControl_NetworkNotAvailable">
 | 
			
		||||
        No wireless network adapter available or turned on
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_NetworkWiredConnected">
 | 
			
		||||
        Connected
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_NetworkWirelessConnected">
 | 
			
		||||
        Connected to "%%NAME%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_NetworkWirelessConnecting">
 | 
			
		||||
        Connecting...
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="Version">
 | 
			
		||||
        Version
 | 
			
		||||
    </Entry>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -597,18 +597,21 @@
 | 
			
		|||
    <Entry key="SystemControl_KeyboardLayoutTooltip">
 | 
			
		||||
        La disposition actuelle du clavier est "%%LAYOUT%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnected">
 | 
			
		||||
        Connecté à "%%NAME%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnecting">
 | 
			
		||||
        Connection en cours...
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessDisconnected">
 | 
			
		||||
    <Entry key="SystemControl_NetworkDisconnected">
 | 
			
		||||
        Déconnecté
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessNotAvailable">
 | 
			
		||||
    <Entry key="SystemControl_NetworkNotAvailable">
 | 
			
		||||
        Pas d'adaptateur réseau sans fil disponible ou allumé
 | 
			
		||||
    </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">
 | 
			
		||||
        Version
 | 
			
		||||
    </Entry>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -597,18 +597,21 @@
 | 
			
		|||
    <Entry key="SystemControl_KeyboardLayoutTooltip">
 | 
			
		||||
        L'attuale layout della tastiera è "%%LAYOUT%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnected">
 | 
			
		||||
        Collegato a "%%NAME%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnecting">
 | 
			
		||||
        Collegamento...
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessDisconnected">
 | 
			
		||||
    <Entry key="SystemControl_NetworkDisconnected">
 | 
			
		||||
        Disconnesso
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessNotAvailable">
 | 
			
		||||
    <Entry key="SystemControl_NetworkNotAvailable">
 | 
			
		||||
        Nessun adattatore di rete wireless disponibile o attivato
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_NetworkWiredConnected">
 | 
			
		||||
        Collegato
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_NetworkWirelessConnected">
 | 
			
		||||
        Collegato a "%%NAME%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_NetworkWirelessConnecting">
 | 
			
		||||
        Collegamento...
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="Version">
 | 
			
		||||
        Versione
 | 
			
		||||
    </Entry>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -531,18 +531,21 @@
 | 
			
		|||
    <Entry key="SystemControl_KeyboardLayoutTooltip">
 | 
			
		||||
        当前键盘布局是 "%%LAYOUT%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnected">
 | 
			
		||||
        已连接到 "%%NAME%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessConnecting">
 | 
			
		||||
        正在连接...
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessDisconnected">
 | 
			
		||||
    <Entry key="SystemControl_NetworkDisconnected">
 | 
			
		||||
        连接已断开
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_WirelessNotAvailable">
 | 
			
		||||
    <Entry key="SystemControl_NetworkNotAvailable">
 | 
			
		||||
        没有无线网卡或未启用无线网卡
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_NetworkWiredConnected">
 | 
			
		||||
        连接的
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_NetworkWirelessConnected">
 | 
			
		||||
        已连接到 "%%NAME%%"
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="SystemControl_NetworkWirelessConnecting">
 | 
			
		||||
        正在连接...
 | 
			
		||||
    </Entry>
 | 
			
		||||
    <Entry key="Version">
 | 
			
		||||
        版本
 | 
			
		||||
    </Entry>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,7 +149,7 @@ namespace SafeExamBrowser.Runtime
 | 
			
		|||
			var xmlParser = new XmlParser(compressor, ModuleLogger(nameof(XmlParser)));
 | 
			
		||||
			var xmlSerializer = new XmlSerializer(ModuleLogger(nameof(XmlSerializer)));
 | 
			
		||||
 | 
			
		||||
			configuration = new ConfigurationRepository(certificateStore, new HashAlgorithm(), repositoryLogger);
 | 
			
		||||
			configuration = new ConfigurationRepository(certificateStore, repositoryLogger);
 | 
			
		||||
			appConfig = configuration.InitializeAppConfig();
 | 
			
		||||
 | 
			
		||||
			configuration.Register(new BinaryParser(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,8 +26,8 @@ using SafeExamBrowser.Server.Data;
 | 
			
		|||
using SafeExamBrowser.Settings.Logging;
 | 
			
		||||
using SafeExamBrowser.Settings.Server;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using Timer = System.Timers.Timer;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.Server
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ namespace SafeExamBrowser.Server
 | 
			
		|||
		private readonly IPowerSupply powerSupply;
 | 
			
		||||
		private readonly ISystemInfo systemInfo;
 | 
			
		||||
		private readonly IUserInfo userInfo;
 | 
			
		||||
		private readonly IWirelessAdapter wirelessAdapter;
 | 
			
		||||
		private readonly INetworkAdapter networkAdapter;
 | 
			
		||||
 | 
			
		||||
		private ApiVersion1 api;
 | 
			
		||||
		private string connectionToken;
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ namespace SafeExamBrowser.Server
 | 
			
		|||
			ISystemInfo systemInfo,
 | 
			
		||||
			IUserInfo userInfo,
 | 
			
		||||
			IPowerSupply powerSupply = default,
 | 
			
		||||
			IWirelessAdapter wirelessAdapter = default)
 | 
			
		||||
			INetworkAdapter networkAdapter = default)
 | 
			
		||||
		{
 | 
			
		||||
			this.api = new ApiVersion1();
 | 
			
		||||
			this.appConfig = appConfig;
 | 
			
		||||
| 
						 | 
				
			
			@ -79,12 +79,12 @@ namespace SafeExamBrowser.Server
 | 
			
		|||
			this.logger = logger;
 | 
			
		||||
			this.logContent = new ConcurrentQueue<ILogContent>();
 | 
			
		||||
			this.logTimer = new Timer();
 | 
			
		||||
			this.networkAdapter = networkAdapter;
 | 
			
		||||
			this.parser = new Parser(logger);
 | 
			
		||||
			this.pingTimer = new Timer();
 | 
			
		||||
			this.powerSupply = powerSupply;
 | 
			
		||||
			this.systemInfo = systemInfo;
 | 
			
		||||
			this.userInfo = userInfo;
 | 
			
		||||
			this.wirelessAdapter = wirelessAdapter;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ServerResponse Connect()
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +226,7 @@ namespace SafeExamBrowser.Server
 | 
			
		|||
		public void Initialize(ServerSettings settings)
 | 
			
		||||
		{
 | 
			
		||||
			this.settings = settings;
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			httpClient = new HttpClient();
 | 
			
		||||
			httpClient.BaseAddress = new Uri(settings.ServerUrl);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -348,20 +348,20 @@ namespace SafeExamBrowser.Server
 | 
			
		|||
			pingTimer.Start();
 | 
			
		||||
			logger.Info("Started sending pings.");
 | 
			
		||||
 | 
			
		||||
			if (powerSupply != default(IPowerSupply) && wirelessAdapter != default(IWirelessAdapter))
 | 
			
		||||
			if (powerSupply != default && networkAdapter != default)
 | 
			
		||||
			{
 | 
			
		||||
				powerSupply.StatusChanged += PowerSupply_StatusChanged;
 | 
			
		||||
				wirelessAdapter.NetworksChanged += WirelessAdapter_NetworksChanged;
 | 
			
		||||
				networkAdapter.Changed += NetworkAdapter_Changed;
 | 
			
		||||
				logger.Info("Started monitoring system components.");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void StopConnectivity()
 | 
			
		||||
		{
 | 
			
		||||
			if (powerSupply != default(IPowerSupply) && wirelessAdapter != default(IWirelessAdapter))
 | 
			
		||||
			if (powerSupply != default && networkAdapter != default)
 | 
			
		||||
			{
 | 
			
		||||
				powerSupply.StatusChanged -= PowerSupply_StatusChanged;
 | 
			
		||||
				wirelessAdapter.NetworksChanged -= WirelessAdapter_NetworksChanged;
 | 
			
		||||
				networkAdapter.Changed -= NetworkAdapter_Changed;
 | 
			
		||||
				logger.Info("Stopped monitoring system components.");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -477,7 +477,7 @@ namespace SafeExamBrowser.Server
 | 
			
		|||
					SendPowerSupplyStatus(text, value);
 | 
			
		||||
					currentPowerSupplyValue = value;
 | 
			
		||||
				}
 | 
			
		||||
				else if (connected != connectedToPowergrid) 
 | 
			
		||||
				else if (connected != connectedToPowergrid)
 | 
			
		||||
				{
 | 
			
		||||
					var text = $"<battery> Device has been {(connected ? "connected to" : "disconnected from")} power grid";
 | 
			
		||||
					SendPowerSupplyStatus(text, value);
 | 
			
		||||
| 
						 | 
				
			
			@ -507,13 +507,13 @@ namespace SafeExamBrowser.Server
 | 
			
		|||
			TryExecute(HttpMethod.Post, api.LogEndpoint, out _, content, contentType, authorization, token);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WirelessAdapter_NetworksChanged()
 | 
			
		||||
		private void NetworkAdapter_Changed()
 | 
			
		||||
		{
 | 
			
		||||
			const int NOT_CONNECTED = -1;
 | 
			
		||||
 | 
			
		||||
			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)
 | 
			
		||||
				{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ namespace SafeExamBrowser.Settings.UserInterface
 | 
			
		|||
		/// Determines whether the application log is accessible via the action center.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public bool ShowApplicationLog { get; set; }
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Determines whether the system control for audio is accessible via the action center.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -47,8 +47,8 @@ namespace SafeExamBrowser.Settings.UserInterface
 | 
			
		|||
		public bool ShowKeyboardLayout { get; set; }
 | 
			
		||||
 | 
			
		||||
		/// <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>
 | 
			
		||||
		public bool ShowWirelessNetwork { get; set; }
 | 
			
		||||
		public bool ShowNetwork { get; set; }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,8 +47,8 @@ namespace SafeExamBrowser.Settings.UserInterface
 | 
			
		|||
		public bool ShowKeyboardLayout { get; set; }
 | 
			
		||||
 | 
			
		||||
		/// <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>
 | 
			
		||||
		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/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork
 | 
			
		||||
namespace SafeExamBrowser.SystemComponents.Contracts.Network
 | 
			
		||||
{
 | 
			
		||||
	/// <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>
 | 
			
		||||
	public enum WirelessNetworkStatus
 | 
			
		||||
	public enum ConnectionStatus
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The connection status is not determinable.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Undefined = 0,
 | 
			
		||||
 | 
			
		||||
		/// <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/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork.Events
 | 
			
		||||
namespace SafeExamBrowser.SystemComponents.Contracts.Network.Events
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Indicates that the available wireless networks have changed.
 | 
			
		||||
	/// Indicates that the network adapter has changed.
 | 
			
		||||
	/// </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;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork
 | 
			
		||||
namespace SafeExamBrowser.SystemComponents.Contracts.Network
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Defines a wireless network which can be connected to by the application.
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +33,6 @@ namespace SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork
 | 
			
		|||
		/// <summary>
 | 
			
		||||
		/// The connection status of this network.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		WirelessNetworkStatus Status { get; }
 | 
			
		||||
		ConnectionStatus Status { get; }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -59,6 +59,7 @@
 | 
			
		|||
    <Compile Include="IFileSystem.cs" />
 | 
			
		||||
    <Compile Include="IRemoteSessionDetector.cs" />
 | 
			
		||||
    <Compile Include="IVirtualMachineDetector.cs" />
 | 
			
		||||
    <Compile Include="Network\ConnectionType.cs" />
 | 
			
		||||
    <Compile Include="PowerSupply\Events\StatusChangedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="PowerSupply\IPowerSupply.cs" />
 | 
			
		||||
    <Compile Include="PowerSupply\BatteryChargeStatus.cs" />
 | 
			
		||||
| 
						 | 
				
			
			@ -68,14 +69,13 @@
 | 
			
		|||
    <Compile Include="ISystemComponent.cs" />
 | 
			
		||||
    <Compile Include="ISystemInfo.cs" />
 | 
			
		||||
    <Compile Include="IUserInfo.cs" />
 | 
			
		||||
    <Compile Include="WirelessNetwork\Events\NetworksChangedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="WirelessNetwork\Events\StatusChangedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="WirelessNetwork\IWirelessAdapter.cs" />
 | 
			
		||||
    <Compile Include="WirelessNetwork\IWirelessNetwork.cs" />
 | 
			
		||||
    <Compile Include="Network\Events\ChangedEventHandler.cs" />
 | 
			
		||||
    <Compile Include="Network\INetworkAdapter.cs" />
 | 
			
		||||
    <Compile Include="Network\IWirelessNetwork.cs" />
 | 
			
		||||
    <Compile Include="OperatingSystem.cs" />
 | 
			
		||||
    <Compile Include="PowerSupply\IPowerSupplyStatus.cs" />
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
    <Compile Include="WirelessNetwork\WirelessNetworkStatus.cs" />
 | 
			
		||||
    <Compile Include="Network\ConnectionStatus.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup />
 | 
			
		||||
  <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 SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SimpleWifi;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.SystemComponents.WirelessNetwork
 | 
			
		||||
namespace SafeExamBrowser.SystemComponents.Network
 | 
			
		||||
{
 | 
			
		||||
	internal class WirelessNetwork : IWirelessNetwork
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ namespace SafeExamBrowser.SystemComponents.WirelessNetwork
 | 
			
		|||
		public Guid Id { get; }
 | 
			
		||||
		public string Name { get; set; }
 | 
			
		||||
		public int SignalStrength { get; set; }
 | 
			
		||||
		public WirelessNetworkStatus Status { get; set; }
 | 
			
		||||
		public ConnectionStatus Status { get; set; }
 | 
			
		||||
 | 
			
		||||
		public WirelessNetwork()
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -101,8 +101,8 @@
 | 
			
		|||
    <Compile Include="SystemInfo.cs" />
 | 
			
		||||
    <Compile Include="UserInfo.cs" />
 | 
			
		||||
    <Compile Include="VirtualMachineDetector.cs" />
 | 
			
		||||
    <Compile Include="WirelessNetwork\WirelessAdapter.cs" />
 | 
			
		||||
    <Compile Include="WirelessNetwork\WirelessNetwork.cs" />
 | 
			
		||||
    <Compile Include="Network\NetworkAdapter.cs" />
 | 
			
		||||
    <Compile Include="Network\WirelessNetwork.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +117,10 @@
 | 
			
		|||
      <Project>{903129c6-e236-493b-9ad6-c6a57f647a3a}</Project>
 | 
			
		||||
      <Name>SafeExamBrowser.SystemComponents.Contracts</Name>
 | 
			
		||||
    </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>
 | 
			
		||||
    <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.SystemComponents.Contracts.Audio;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +78,11 @@ namespace SafeExamBrowser.UserInterface.Contracts
 | 
			
		|||
		/// </summary>
 | 
			
		||||
		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>
 | 
			
		||||
		/// Creates a notification control for the given notification, initialized for the specified location.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -132,10 +137,5 @@ namespace SafeExamBrowser.UserInterface.Contracts
 | 
			
		|||
		/// Creates a new taskview.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		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:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 | 
			
		||||
| 
						 | 
				
			
			@ -9,17 +9,17 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
 | 
			
		||||
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 WirelessNetworkButton(IWirelessNetwork network)
 | 
			
		||||
		internal NetworkButton(IWirelessNetwork network)
 | 
			
		||||
		{
 | 
			
		||||
			this.network = network;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenter
 | 
			
		|||
		private void InitializeNetworkButton()
 | 
			
		||||
		{
 | 
			
		||||
			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;
 | 
			
		||||
			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:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             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}">
 | 
			
		||||
            <Border Background="Gray">
 | 
			
		||||
                <ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
 | 
			
		||||
                    <StackPanel x:Name="NetworksStackPanel" />
 | 
			
		||||
                    <StackPanel x:Name="WirelessNetworksStackPanel" />
 | 
			
		||||
                </ScrollViewer>
 | 
			
		||||
            </Border>
 | 
			
		||||
        </Popup>
 | 
			
		||||
| 
						 | 
				
			
			@ -30,10 +30,11 @@
 | 
			
		|||
                    <RowDefinition Height="3*" />
 | 
			
		||||
                </Grid.RowDefinitions>
 | 
			
		||||
                <Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
 | 
			
		||||
                    <Viewbox x:Name="SignalStrengthIcon" Stretch="Uniform" Width="Auto" />
 | 
			
		||||
                    <fa:ImageAwesome x:Name="NoAdapterIcon" Foreground="Red" Icon="Ban" Margin="1" Opacity="0.3" Visibility="Collapsed" />
 | 
			
		||||
                    <fa:ImageAwesome x:Name="LoadingIcon" Foreground="Black" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" />
 | 
			
		||||
                    <Image x:Name="NetworkStatusIcon" Height="7" HorizontalAlignment="Right" Margin="-2,0" Panel.ZIndex="10" VerticalAlignment="Bottom" />
 | 
			
		||||
                    <Viewbox x:Name="WirelessIcon" Stretch="Uniform" Width="Auto" Visibility="Collapsed" />
 | 
			
		||||
                    <fa:ImageAwesome x:Name="WiredIcon" Icon="Tv" Margin="0,2,4,4" Visibility="Collapsed" />
 | 
			
		||||
                    <Border Background="White" CornerRadius="6" Height="12" HorizontalAlignment="Right" Margin="-3,0" Panel.ZIndex="10" VerticalAlignment="Bottom">
 | 
			
		||||
                        <fa:ImageAwesome x:Name="NetworkStatusIcon" />
 | 
			
		||||
                    </Border>
 | 
			
		||||
                </Grid>
 | 
			
		||||
                <TextBlock Grid.Row="1" x:Name="Text" FontSize="11" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
 | 
			
		||||
            </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:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 | 
			
		||||
| 
						 | 
				
			
			@ -9,17 +9,17 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
 | 
			
		||||
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 WirelessNetworkButton(IWirelessNetwork network)
 | 
			
		||||
		internal NetworkButton(IWirelessNetwork network)
 | 
			
		||||
		{
 | 
			
		||||
			this.network = network;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
 | 
			
		|||
		private void InitializeNetworkButton()
 | 
			
		||||
		{
 | 
			
		||||
			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;
 | 
			
		||||
			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:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             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}">
 | 
			
		||||
            <Border Background="LightGray" BorderBrush="Gray" BorderThickness="1,1,1,0">
 | 
			
		||||
                <ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
 | 
			
		||||
                    <StackPanel x:Name="NetworksStackPanel" />
 | 
			
		||||
                    <StackPanel x:Name="WirelessNetworksStackPanel" />
 | 
			
		||||
                </ScrollViewer>
 | 
			
		||||
            </Border>
 | 
			
		||||
        </Popup>
 | 
			
		||||
        <Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="40">
 | 
			
		||||
            <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
 | 
			
		||||
                <Viewbox x:Name="SignalStrengthIcon" Stretch="Uniform" Width="Auto" />
 | 
			
		||||
                <fa:ImageAwesome x:Name="NoAdapterIcon" Foreground="Red" Icon="Ban" Margin="1" Opacity="0.3" Visibility="Collapsed" />
 | 
			
		||||
                <fa:ImageAwesome x:Name="LoadingIcon" Foreground="Gray" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" />
 | 
			
		||||
                <Image x:Name="NetworkStatusIcon" Height="7" HorizontalAlignment="Right" Margin="0,2" Panel.ZIndex="10" VerticalAlignment="Bottom" />
 | 
			
		||||
                <Viewbox x:Name="WirelessIcon" Stretch="Uniform" Width="Auto" Visibility="Collapsed" />
 | 
			
		||||
                <fa:ImageAwesome x:Name="WiredIcon" Icon="Tv" Margin="0,2,4,4" Visibility="Collapsed" />
 | 
			
		||||
                <Border Background="{StaticResource BackgroundBrush}" CornerRadius="6" Height="12" HorizontalAlignment="Right" Margin="0,0,-1,1" Panel.ZIndex="10" VerticalAlignment="Bottom">
 | 
			
		||||
                    <fa:ImageAwesome x:Name="NetworkStatusIcon" />
 | 
			
		||||
                </Border>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </Button>
 | 
			
		||||
    </Grid>
 | 
			
		||||
| 
						 | 
				
			
			@ -15,20 +15,20 @@ using System.Windows.Media;
 | 
			
		|||
using FontAwesome.WPF;
 | 
			
		||||
using SafeExamBrowser.Core.Contracts.Resources.Icons;
 | 
			
		||||
using SafeExamBrowser.I18n.Contracts;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
 | 
			
		||||
{
 | 
			
		||||
	internal partial class WirelessNetworkControl : UserControl, ISystemControl
 | 
			
		||||
	internal partial class NetworkControl : UserControl, ISystemControl
 | 
			
		||||
	{
 | 
			
		||||
		private IWirelessAdapter wirelessAdapter;
 | 
			
		||||
		private IText text;
 | 
			
		||||
		private readonly INetworkAdapter adapter;
 | 
			
		||||
		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;
 | 
			
		||||
 | 
			
		||||
			InitializeComponent();
 | 
			
		||||
| 
						 | 
				
			
			@ -44,11 +44,12 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
 | 
			
		|||
		{
 | 
			
		||||
			var originalBrush = Button.Background;
 | 
			
		||||
 | 
			
		||||
			SignalStrengthIcon.Child = GetIcon(0);
 | 
			
		||||
			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.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
 | 
			
		||||
			Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
 | 
			
		||||
			WirelessIcon.Child = GetWirelessIcon(0);
 | 
			
		||||
 | 
			
		||||
			Popup.Opened += (o, args) =>
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -62,18 +63,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls.Taskbar
 | 
			
		|||
				Button.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));
 | 
			
		||||
			}
 | 
			
		||||
			Update();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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)
 | 
			
		||||
		{
 | 
			
		||||
			Dispatcher.InvokeAsync(() => UpdateStatus(status));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void UpdateNetworks()
 | 
			
		||||
		{
 | 
			
		||||
			var status = WirelessNetworkStatus.Disconnected;
 | 
			
		||||
 | 
			
		||||
			NetworksStackPanel.Children.Clear();
 | 
			
		||||
 | 
			
		||||
			foreach (var network in wirelessAdapter.GetNetworks())
 | 
			
		||||
			foreach (var network in adapter.GetWirelessNetworks())
 | 
			
		||||
			{
 | 
			
		||||
				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;
 | 
			
		||||
					SignalStrengthIcon.Child = GetIcon(network.SignalStrength);
 | 
			
		||||
					UpdateText(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", network.Name));
 | 
			
		||||
					WirelessIcon.Child = GetWirelessIcon(network.SignalStrength);
 | 
			
		||||
					Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWirelessConnected).Replace("%%NAME%%", network.Name);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				NetworksStackPanel.Children.Add(button);
 | 
			
		||||
				WirelessNetworksStackPanel.Children.Add(button);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			UpdateStatus(status);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void UpdateStatus(WirelessNetworkStatus status)
 | 
			
		||||
		{
 | 
			
		||||
			LoadingIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
			SignalStrengthIcon.Visibility = Visibility.Visible;
 | 
			
		||||
			NetworkStatusIcon.Visibility = Visibility.Visible;
 | 
			
		||||
 | 
			
		||||
			switch (status)
 | 
			
		||||
			switch (adapter.Type)
 | 
			
		||||
			{
 | 
			
		||||
				case WirelessNetworkStatus.Connected:
 | 
			
		||||
					NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Check, Brushes.Green);
 | 
			
		||||
				case ConnectionType.Wired:
 | 
			
		||||
					Button.IsEnabled = false;
 | 
			
		||||
					Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWiredConnected);
 | 
			
		||||
					WiredIcon.Visibility = Visibility.Visible;
 | 
			
		||||
					WirelessIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
					break;
 | 
			
		||||
				case WirelessNetworkStatus.Connecting:
 | 
			
		||||
					LoadingIcon.Visibility = Visibility.Visible;
 | 
			
		||||
					SignalStrengthIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
					NetworkStatusIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
					UpdateText(text.Get(TextKey.SystemControl_WirelessConnecting));
 | 
			
		||||
				case ConnectionType.Wireless:
 | 
			
		||||
					Button.IsEnabled = true;
 | 
			
		||||
					WiredIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
					WirelessIcon.Visibility = Visibility.Visible;
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Close, Brushes.Orange);
 | 
			
		||||
					SignalStrengthIcon.Child = GetIcon(0);
 | 
			
		||||
					UpdateText(text.Get(TextKey.SystemControl_WirelessDisconnected));
 | 
			
		||||
					Button.IsEnabled = false;
 | 
			
		||||
					Button.ToolTip = 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:
 | 
			
		||||
					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;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void UpdateText(string text)
 | 
			
		||||
		{
 | 
			
		||||
			Button.ToolTip = text;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private UIElement GetIcon(int signalStrength)
 | 
			
		||||
		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_{icon}.xaml");
 | 
			
		||||
| 
						 | 
				
			
			@ -109,11 +109,11 @@
 | 
			
		|||
    <Compile Include="Controls\ActionCenter\QuitButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>QuitButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\ActionCenter\WirelessNetworkButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\ActionCenter\NetworkButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>NetworkButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\ActionCenter\WirelessNetworkControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\ActionCenter\NetworkControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>NetworkControl.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\Browser\DownloadItemControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>DownloadItemControl.xaml</DependentUpon>
 | 
			
		||||
| 
						 | 
				
			
			@ -145,11 +145,11 @@
 | 
			
		|||
    <Compile Include="Controls\Taskbar\QuitButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>QuitButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\Taskbar\WirelessNetworkButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\Taskbar\NetworkButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>NetworkButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\Taskbar\WirelessNetworkControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\Taskbar\NetworkControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>NetworkControl.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\Taskview\WindowControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>WindowControl.xaml</DependentUpon>
 | 
			
		||||
| 
						 | 
				
			
			@ -263,11 +263,11 @@
 | 
			
		|||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\ActionCenter\WirelessNetworkButton.xaml">
 | 
			
		||||
    <Page Include="Controls\ActionCenter\NetworkButton.xaml">
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\ActionCenter\WirelessNetworkControl.xaml">
 | 
			
		||||
    <Page Include="Controls\ActionCenter\NetworkControl.xaml">
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
| 
						 | 
				
			
			@ -451,11 +451,11 @@
 | 
			
		|||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
    </Resource>
 | 
			
		||||
    <Page Include="Controls\Taskbar\WirelessNetworkButton.xaml">
 | 
			
		||||
    <Page Include="Controls\Taskbar\NetworkButton.xaml">
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\Taskbar\WirelessNetworkControl.xaml">
 | 
			
		||||
    <Page Include="Controls\Taskbar\NetworkControl.xaml">
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
    </Page>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,8 +22,8 @@ using SafeExamBrowser.Settings.Browser;
 | 
			
		|||
using SafeExamBrowser.Settings.Proctoring;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Audio;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +37,7 @@ namespace SafeExamBrowser.UserInterface.Desktop
 | 
			
		|||
{
 | 
			
		||||
	public class UserInterfaceFactory : IUserInterfaceFactory
 | 
			
		||||
	{
 | 
			
		||||
		private IText text;
 | 
			
		||||
		private readonly IText text;
 | 
			
		||||
 | 
			
		||||
		public UserInterfaceFactory(IText text)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +131,18 @@ namespace SafeExamBrowser.UserInterface.Desktop
 | 
			
		|||
			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)
 | 
			
		||||
		{
 | 
			
		||||
			if (location == Location.ActionCenter)
 | 
			
		||||
| 
						 | 
				
			
			@ -226,18 +238,6 @@ namespace SafeExamBrowser.UserInterface.Desktop
 | 
			
		|||
			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()
 | 
			
		||||
		{
 | 
			
		||||
			// 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:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 | 
			
		||||
| 
						 | 
				
			
			@ -9,17 +9,17 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
 | 
			
		||||
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 WirelessNetworkButton(IWirelessNetwork network)
 | 
			
		||||
		internal NetworkButton(IWirelessNetwork network)
 | 
			
		||||
		{
 | 
			
		||||
			this.network = network;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.ActionCenter
 | 
			
		|||
		private void InitializeNetworkButton()
 | 
			
		||||
		{
 | 
			
		||||
			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;
 | 
			
		||||
			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:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             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}">
 | 
			
		||||
            <Border Background="Gray">
 | 
			
		||||
                <ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
 | 
			
		||||
                    <StackPanel x:Name="NetworksStackPanel" />
 | 
			
		||||
                    <StackPanel x:Name="WirelessNetworksStackPanel" />
 | 
			
		||||
                </ScrollViewer>
 | 
			
		||||
            </Border>
 | 
			
		||||
        </Popup>
 | 
			
		||||
| 
						 | 
				
			
			@ -30,10 +30,11 @@
 | 
			
		|||
                    <RowDefinition Height="3*" />
 | 
			
		||||
                </Grid.RowDefinitions>
 | 
			
		||||
                <Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
 | 
			
		||||
                    <Viewbox x:Name="SignalStrengthIcon" Stretch="Uniform" Width="Auto" />
 | 
			
		||||
                    <fa:ImageAwesome x:Name="NoAdapterIcon" Foreground="Red" Icon="Ban" Margin="1" Opacity="0.3" Visibility="Collapsed" />
 | 
			
		||||
                    <fa:ImageAwesome x:Name="LoadingIcon" Foreground="Black" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" />
 | 
			
		||||
                    <Image x:Name="NetworkStatusIcon" Height="8" HorizontalAlignment="Right" Margin="-2,0" Panel.ZIndex="10" VerticalAlignment="Bottom" />
 | 
			
		||||
                    <Viewbox x:Name="WirelessIcon" Stretch="Uniform" Width="Auto" Visibility="Collapsed" />
 | 
			
		||||
                    <fa:ImageAwesome x:Name="WiredIcon" Icon="Tv" Margin="0,2,4,4" Visibility="Collapsed" />
 | 
			
		||||
                    <Border Background="White" CornerRadius="6" Height="14" HorizontalAlignment="Right" Margin="-3,0" Panel.ZIndex="10" VerticalAlignment="Bottom">
 | 
			
		||||
                        <fa:ImageAwesome x:Name="NetworkStatusIcon" />
 | 
			
		||||
                    </Border>
 | 
			
		||||
                </Grid>
 | 
			
		||||
                <TextBlock Grid.Row="1" x:Name="Text" FontSize="15" Foreground="White" TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" VerticalAlignment="Bottom" />
 | 
			
		||||
            </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:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 | 
			
		||||
| 
						 | 
				
			
			@ -9,17 +9,17 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
 | 
			
		||||
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 WirelessNetworkButton(IWirelessNetwork network)
 | 
			
		||||
		internal NetworkButton(IWirelessNetwork network)
 | 
			
		||||
		{
 | 
			
		||||
			this.network = network;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
 | 
			
		|||
		private void InitializeNetworkButton()
 | 
			
		||||
		{
 | 
			
		||||
			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;
 | 
			
		||||
			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:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
			
		||||
             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}">
 | 
			
		||||
            <Border Background="LightGray" BorderBrush="Gray" BorderThickness="1,1,1,0">
 | 
			
		||||
                <ScrollViewer MaxHeight="250" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
 | 
			
		||||
                    <StackPanel x:Name="NetworksStackPanel" />
 | 
			
		||||
                    <StackPanel x:Name="WirelessNetworksStackPanel" />
 | 
			
		||||
                </ScrollViewer>
 | 
			
		||||
            </Border>
 | 
			
		||||
        </Popup>
 | 
			
		||||
        <Button x:Name="Button" Background="Transparent" Padding="5" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True" Width="60">
 | 
			
		||||
            <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
 | 
			
		||||
                <Viewbox x:Name="SignalStrengthIcon" Stretch="Uniform" Width="Auto" />
 | 
			
		||||
                <fa:ImageAwesome x:Name="NoAdapterIcon" Foreground="Red" Icon="Ban" Margin="1" Opacity="0.3" Visibility="Collapsed" />
 | 
			
		||||
                <fa:ImageAwesome x:Name="LoadingIcon" Foreground="Gray" Icon="Cog" Margin="5" Spin="True" SpinDuration="2" Visibility="Collapsed" />
 | 
			
		||||
                <Image x:Name="NetworkStatusIcon" Height="12" HorizontalAlignment="Right" Margin="0,2" Panel.ZIndex="10" VerticalAlignment="Bottom" />
 | 
			
		||||
                <Viewbox x:Name="WirelessIcon" Stretch="Uniform" Width="Auto" Visibility="Collapsed" />
 | 
			
		||||
                <fa:ImageAwesome x:Name="WiredIcon" Icon="Tv" Margin="0,2,4,4" Visibility="Collapsed" />
 | 
			
		||||
                <Border Background="{StaticResource BackgroundBrush}" CornerRadius="6" Height="18" HorizontalAlignment="Right" Margin="0,0,-1,1" Panel.ZIndex="10" VerticalAlignment="Bottom">
 | 
			
		||||
                    <fa:ImageAwesome x:Name="NetworkStatusIcon" />
 | 
			
		||||
                </Border>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </Button>
 | 
			
		||||
    </Grid>
 | 
			
		||||
| 
						 | 
				
			
			@ -15,20 +15,20 @@ using System.Windows.Media;
 | 
			
		|||
using FontAwesome.WPF;
 | 
			
		||||
using SafeExamBrowser.Core.Contracts.Resources.Icons;
 | 
			
		||||
using SafeExamBrowser.I18n.Contracts;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Shared.Utilities;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
 | 
			
		||||
{
 | 
			
		||||
	internal partial class WirelessNetworkControl : UserControl, ISystemControl
 | 
			
		||||
	internal partial class NetworkControl : UserControl, ISystemControl
 | 
			
		||||
	{
 | 
			
		||||
		private IWirelessAdapter wirelessAdapter;
 | 
			
		||||
		private IText text;
 | 
			
		||||
		private readonly INetworkAdapter adapter;
 | 
			
		||||
		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;
 | 
			
		||||
 | 
			
		||||
			InitializeComponent();
 | 
			
		||||
| 
						 | 
				
			
			@ -44,11 +44,12 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
 | 
			
		|||
		{
 | 
			
		||||
			var originalBrush = Button.Background;
 | 
			
		||||
 | 
			
		||||
			SignalStrengthIcon.Child = GetIcon(0);
 | 
			
		||||
			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.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(Popup_PlacementCallback);
 | 
			
		||||
			Popup.MouseLeave += (o, args) => Task.Delay(250).ContinueWith(_ => Dispatcher.Invoke(() => Popup.IsOpen = IsMouseOver));
 | 
			
		||||
			WirelessIcon.Child = GetWirelessIcon(0);
 | 
			
		||||
 | 
			
		||||
			Popup.Opened += (o, args) =>
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -62,18 +63,7 @@ namespace SafeExamBrowser.UserInterface.Mobile.Controls.Taskbar
 | 
			
		|||
				Button.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));
 | 
			
		||||
			}
 | 
			
		||||
			Update();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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)
 | 
			
		||||
		{
 | 
			
		||||
			Dispatcher.InvokeAsync(() => UpdateStatus(status));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void UpdateNetworks()
 | 
			
		||||
		{
 | 
			
		||||
			var status = WirelessNetworkStatus.Disconnected;
 | 
			
		||||
 | 
			
		||||
			NetworksStackPanel.Children.Clear();
 | 
			
		||||
 | 
			
		||||
			foreach (var network in wirelessAdapter.GetNetworks())
 | 
			
		||||
			foreach (var network in adapter.GetWirelessNetworks())
 | 
			
		||||
			{
 | 
			
		||||
				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;
 | 
			
		||||
					SignalStrengthIcon.Child = GetIcon(network.SignalStrength);
 | 
			
		||||
					UpdateText(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", network.Name));
 | 
			
		||||
					WirelessIcon.Child = GetWirelessIcon(network.SignalStrength);
 | 
			
		||||
					Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWirelessConnected).Replace("%%NAME%%", network.Name);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				NetworksStackPanel.Children.Add(button);
 | 
			
		||||
				WirelessNetworksStackPanel.Children.Add(button);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			UpdateStatus(status);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void UpdateStatus(WirelessNetworkStatus status)
 | 
			
		||||
		{
 | 
			
		||||
			LoadingIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
			SignalStrengthIcon.Visibility = Visibility.Visible;
 | 
			
		||||
			NetworkStatusIcon.Visibility = Visibility.Visible;
 | 
			
		||||
 | 
			
		||||
			switch (status)
 | 
			
		||||
			switch (adapter.Type)
 | 
			
		||||
			{
 | 
			
		||||
				case WirelessNetworkStatus.Connected:
 | 
			
		||||
					NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Check, Brushes.Green);
 | 
			
		||||
				case ConnectionType.Wired:
 | 
			
		||||
					Button.IsEnabled = false;
 | 
			
		||||
					Button.ToolTip = text.Get(TextKey.SystemControl_NetworkWiredConnected);
 | 
			
		||||
					WiredIcon.Visibility = Visibility.Visible;
 | 
			
		||||
					WirelessIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
					break;
 | 
			
		||||
				case WirelessNetworkStatus.Connecting:
 | 
			
		||||
					LoadingIcon.Visibility = Visibility.Visible;
 | 
			
		||||
					SignalStrengthIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
					NetworkStatusIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
					UpdateText(text.Get(TextKey.SystemControl_WirelessConnecting));
 | 
			
		||||
				case ConnectionType.Wireless:
 | 
			
		||||
					Button.IsEnabled = true;
 | 
			
		||||
					WiredIcon.Visibility = Visibility.Collapsed;
 | 
			
		||||
					WirelessIcon.Visibility = Visibility.Visible;
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					NetworkStatusIcon.Source = ImageAwesome.CreateImageSource(FontAwesomeIcon.Close, Brushes.Orange);
 | 
			
		||||
					SignalStrengthIcon.Child = GetIcon(0);
 | 
			
		||||
					UpdateText(text.Get(TextKey.SystemControl_WirelessDisconnected));
 | 
			
		||||
					Button.IsEnabled = false;
 | 
			
		||||
					Button.ToolTip = 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:
 | 
			
		||||
					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;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void UpdateText(string text)
 | 
			
		||||
		{
 | 
			
		||||
			Button.ToolTip = text;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private UIElement GetIcon(int signalStrength)
 | 
			
		||||
		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_{icon}.xaml");
 | 
			
		||||
| 
						 | 
				
			
			@ -110,11 +110,11 @@
 | 
			
		|||
    <Compile Include="Controls\ActionCenter\QuitButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>QuitButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\ActionCenter\WirelessNetworkButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\ActionCenter\NetworkButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>NetworkButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\ActionCenter\WirelessNetworkControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\ActionCenter\NetworkControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>NetworkControl.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\Browser\DownloadItemControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>DownloadItemControl.xaml</DependentUpon>
 | 
			
		||||
| 
						 | 
				
			
			@ -146,11 +146,11 @@
 | 
			
		|||
    <Compile Include="Controls\Taskbar\QuitButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>QuitButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\Taskbar\WirelessNetworkButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\Taskbar\NetworkButton.xaml.cs">
 | 
			
		||||
      <DependentUpon>NetworkButton.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\Taskbar\WirelessNetworkControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
 | 
			
		||||
    <Compile Include="Controls\Taskbar\NetworkControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>NetworkControl.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Controls\Taskview\WindowControl.xaml.cs">
 | 
			
		||||
      <DependentUpon>WindowControl.xaml</DependentUpon>
 | 
			
		||||
| 
						 | 
				
			
			@ -321,11 +321,11 @@
 | 
			
		|||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\ActionCenter\WirelessNetworkButton.xaml">
 | 
			
		||||
    <Page Include="Controls\ActionCenter\NetworkButton.xaml">
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\ActionCenter\WirelessNetworkControl.xaml">
 | 
			
		||||
    <Page Include="Controls\ActionCenter\NetworkControl.xaml">
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
    </Page>
 | 
			
		||||
| 
						 | 
				
			
			@ -369,11 +369,11 @@
 | 
			
		|||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\Taskbar\WirelessNetworkButton.xaml">
 | 
			
		||||
    <Page Include="Controls\Taskbar\NetworkButton.xaml">
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
    </Page>
 | 
			
		||||
    <Page Include="Controls\Taskbar\WirelessNetworkControl.xaml">
 | 
			
		||||
    <Page Include="Controls\Taskbar\NetworkControl.xaml">
 | 
			
		||||
      <Generator>MSBuild:Compile</Generator>
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
    </Page>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,8 +22,8 @@ using SafeExamBrowser.Settings.Browser;
 | 
			
		|||
using SafeExamBrowser.Settings.Proctoring;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Audio;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
 | 
			
		||||
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
 | 
			
		||||
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +37,7 @@ namespace SafeExamBrowser.UserInterface.Mobile
 | 
			
		|||
{
 | 
			
		||||
	public class UserInterfaceFactory : IUserInterfaceFactory
 | 
			
		||||
	{
 | 
			
		||||
		private IText text;
 | 
			
		||||
		private readonly IText text;
 | 
			
		||||
 | 
			
		||||
		public UserInterfaceFactory(IText text)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +131,18 @@ namespace SafeExamBrowser.UserInterface.Mobile
 | 
			
		|||
			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)
 | 
			
		||||
		{
 | 
			
		||||
			if (location == Location.ActionCenter)
 | 
			
		||||
| 
						 | 
				
			
			@ -226,18 +238,6 @@ namespace SafeExamBrowser.UserInterface.Mobile
 | 
			
		|||
			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()
 | 
			
		||||
		{
 | 
			
		||||
			// 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>
 | 
			
		||||
		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>
 | 
			
		||||
		/// Hides the given window. Returns <c>true</c> if successful, otherwise <c>false</c>.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,9 @@ namespace SafeExamBrowser.WindowsApi
 | 
			
		|||
{
 | 
			
		||||
	public class NativeMethods : INativeMethods
 | 
			
		||||
	{
 | 
			
		||||
		private ConcurrentDictionary<Guid, KeyboardHook> KeyboardHooks = new ConcurrentDictionary<Guid, KeyboardHook>();
 | 
			
		||||
		private ConcurrentDictionary<Guid, MouseHook> MouseHooks = new ConcurrentDictionary<Guid, MouseHook>();
 | 
			
		||||
		private ConcurrentDictionary<Guid, SystemHook> SystemHooks = new ConcurrentDictionary<Guid, SystemHook>();
 | 
			
		||||
		private readonly ConcurrentDictionary<Guid, KeyboardHook> KeyboardHooks = new ConcurrentDictionary<Guid, KeyboardHook>();
 | 
			
		||||
		private readonly ConcurrentDictionary<Guid, MouseHook> MouseHooks = new ConcurrentDictionary<Guid, MouseHook>();
 | 
			
		||||
		private readonly ConcurrentDictionary<Guid, SystemHook> SystemHooks = new ConcurrentDictionary<Guid, SystemHook>();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Upon finalization, unregister all active system events and hooks...
 | 
			
		||||
| 
						 | 
				
			
			@ -245,6 +245,11 @@ namespace SafeExamBrowser.WindowsApi
 | 
			
		|||
			return workingArea.ToBounds();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool HasInternetConnection()
 | 
			
		||||
		{
 | 
			
		||||
			return WinInet.InternetGetConnectedState(out _, 0);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool HideWindow(IntPtr window)
 | 
			
		||||
		{
 | 
			
		||||
			return User32.ShowWindow(window, (int) ShowWindowCommand.Hide);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,6 +92,7 @@
 | 
			
		|||
    <Compile Include="Types\Window.cs" />
 | 
			
		||||
    <Compile Include="Types\WINDOWPLACEMENT.cs" />
 | 
			
		||||
    <Compile Include="User32.cs" />
 | 
			
		||||
    <Compile Include="WinInet.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <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…
	
	Add table
		
		Reference in a new issue