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…
Reference in a new issue