SEBWIN-141: Extended system component contracts and implementations to allow multiple controls per component and started to implement action center functionality.
This commit is contained in:
parent
519fb9e57b
commit
31857bfb25
26 changed files with 579 additions and 476 deletions
|
@ -44,16 +44,11 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustPeformCorrectly()
|
public void MustPeformCorrectly()
|
||||||
{
|
{
|
||||||
var order = 0;
|
|
||||||
|
|
||||||
controller.Setup(c => c.Initialize()).Callback(() => Assert.AreEqual(++order, 1));
|
|
||||||
controller.Setup(c => c.RegisterApplicationControl(It.IsAny<IApplicationControl>())).Callback(() => Assert.AreEqual(++order, 2));
|
|
||||||
taskbar.Setup(t => t.AddApplicationControl(It.IsAny<IApplicationControl>())).Callback(() => Assert.AreEqual(++order, 3));
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
controller.Verify(c => c.Initialize(), Times.Once);
|
controller.Verify(c => c.Initialize(), Times.Once);
|
||||||
controller.Verify(c => c.RegisterApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
|
controller.Verify(c => c.RegisterApplicationControl(It.IsAny<IApplicationControl>()), Times.Exactly(2));
|
||||||
|
actionCenter.Verify(a => a.AddApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
|
||||||
taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
|
taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +56,6 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
public void MustRevertCorrectly()
|
public void MustRevertCorrectly()
|
||||||
{
|
{
|
||||||
sut.Revert();
|
sut.Revert();
|
||||||
|
|
||||||
controller.Verify(c => c.Terminate(), Times.Once);
|
controller.Verify(c => c.Terminate(), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using Moq;
|
using Moq;
|
||||||
using SafeExamBrowser.Client.Operations;
|
using SafeExamBrowser.Client.Operations;
|
||||||
|
@ -19,10 +20,13 @@ using SafeExamBrowser.Contracts.UserInterface.Shell;
|
||||||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
{
|
{
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class TaskbarOperationTests
|
public class ShellOperationTests
|
||||||
{
|
{
|
||||||
|
private Mock<IActionCenter> actionCenter;
|
||||||
|
private Mock<IEnumerable<IActionCenterActivator>> activators;
|
||||||
|
private ActionCenterSettings actionCenterSettings;
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private TaskbarSettings settings;
|
private TaskbarSettings taskbarSettings;
|
||||||
private Mock<INotificationInfo> aboutInfoMock;
|
private Mock<INotificationInfo> aboutInfoMock;
|
||||||
private Mock<INotificationController> aboutControllerMock;
|
private Mock<INotificationController> aboutControllerMock;
|
||||||
private Mock<INotificationInfo> logInfoMock;
|
private Mock<INotificationInfo> logInfoMock;
|
||||||
|
@ -34,11 +38,14 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
private Mock<ITaskbar> taskbarMock;
|
private Mock<ITaskbar> taskbarMock;
|
||||||
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
||||||
|
|
||||||
private TaskbarOperation sut;
|
private ShellOperation sut;
|
||||||
|
|
||||||
[TestInitialize]
|
[TestInitialize]
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
|
actionCenter = new Mock<IActionCenter>();
|
||||||
|
activators = new Mock<IEnumerable<IActionCenterActivator>>();
|
||||||
|
actionCenterSettings = new ActionCenterSettings();
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
aboutInfoMock = new Mock<INotificationInfo>();
|
aboutInfoMock = new Mock<INotificationInfo>();
|
||||||
aboutControllerMock = new Mock<INotificationController>();
|
aboutControllerMock = new Mock<INotificationController>();
|
||||||
|
@ -49,17 +56,20 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
wirelessNetworkMock = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
|
wirelessNetworkMock = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
|
||||||
systemInfoMock = new Mock<ISystemInfo>();
|
systemInfoMock = new Mock<ISystemInfo>();
|
||||||
taskbarMock = new Mock<ITaskbar>();
|
taskbarMock = new Mock<ITaskbar>();
|
||||||
settings = new TaskbarSettings();
|
taskbarSettings = new TaskbarSettings();
|
||||||
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
||||||
|
|
||||||
settings.AllowApplicationLog = true;
|
taskbarSettings.AllowApplicationLog = true;
|
||||||
settings.AllowKeyboardLayout = true;
|
taskbarSettings.AllowKeyboardLayout = true;
|
||||||
settings.AllowWirelessNetwork = true;
|
taskbarSettings.AllowWirelessNetwork = true;
|
||||||
settings.EnableTaskbar = true;
|
taskbarSettings.EnableTaskbar = true;
|
||||||
systemInfoMock.SetupGet(s => s.HasBattery).Returns(true);
|
systemInfoMock.SetupGet(s => s.HasBattery).Returns(true);
|
||||||
uiFactoryMock.Setup(u => u.CreateNotificationControl(It.IsAny<INotificationInfo>())).Returns(new Mock<INotificationControl>().Object);
|
uiFactoryMock.Setup(u => u.CreateNotificationControl(It.IsAny<INotificationInfo>(), It.IsAny<Location>())).Returns(new Mock<INotificationControl>().Object);
|
||||||
|
|
||||||
sut = new TaskbarOperation(
|
sut = new ShellOperation(
|
||||||
|
actionCenter.Object,
|
||||||
|
activators.Object,
|
||||||
|
actionCenterSettings,
|
||||||
loggerMock.Object,
|
loggerMock.Object,
|
||||||
aboutInfoMock.Object,
|
aboutInfoMock.Object,
|
||||||
aboutControllerMock.Object,
|
aboutControllerMock.Object,
|
||||||
|
@ -70,7 +80,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
wirelessNetworkMock.Object,
|
wirelessNetworkMock.Object,
|
||||||
systemInfoMock.Object,
|
systemInfoMock.Object,
|
||||||
taskbarMock.Object,
|
taskbarMock.Object,
|
||||||
settings,
|
taskbarSettings,
|
||||||
uiFactoryMock.Object);
|
uiFactoryMock.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,9 +89,9 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||||
{
|
{
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
keyboardLayoutMock.Verify(k => k.Initialize(It.IsAny<ISystemKeyboardLayoutControl>()), Times.Once);
|
keyboardLayoutMock.Verify(k => k.Initialize(), Times.Once);
|
||||||
powerSupplyMock.Verify(p => p.Initialize(It.IsAny<ISystemPowerSupplyControl>()), Times.Once);
|
powerSupplyMock.Verify(p => p.Initialize(), Times.Once);
|
||||||
wirelessNetworkMock.Verify(w => w.Initialize(It.IsAny<ISystemWirelessNetworkControl>()), Times.Once);
|
wirelessNetworkMock.Verify(w => w.Initialize(), Times.Once);
|
||||||
taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(3));
|
taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(3));
|
||||||
taskbarMock.Verify(t => t.AddNotificationControl(It.IsAny<INotificationControl>()), Times.Exactly(2));
|
taskbarMock.Verify(t => t.AddNotificationControl(It.IsAny<INotificationControl>()), Times.Exactly(2));
|
||||||
}
|
}
|
|
@ -90,7 +90,7 @@
|
||||||
<Compile Include="Operations\MouseInterceptorOperationTests.cs" />
|
<Compile Include="Operations\MouseInterceptorOperationTests.cs" />
|
||||||
<Compile Include="Operations\ProcessMonitorOperationTests.cs" />
|
<Compile Include="Operations\ProcessMonitorOperationTests.cs" />
|
||||||
<Compile Include="Operations\RuntimeConnectionOperationTests.cs" />
|
<Compile Include="Operations\RuntimeConnectionOperationTests.cs" />
|
||||||
<Compile Include="Operations\TaskbarOperationTests.cs" />
|
<Compile Include="Operations\ShellOperationTests.cs" />
|
||||||
<Compile Include="Operations\WindowMonitorOperationTests.cs" />
|
<Compile Include="Operations\WindowMonitorOperationTests.cs" />
|
||||||
<Compile Include="Communication\ClientHostTests.cs" />
|
<Compile Include="Communication\ClientHostTests.cs" />
|
||||||
<Compile Include="Notifications\AboutNotificationControllerTests.cs" />
|
<Compile Include="Notifications\AboutNotificationControllerTests.cs" />
|
||||||
|
|
|
@ -116,8 +116,7 @@ namespace SafeExamBrowser.Client
|
||||||
operations.Enqueue(new LazyInitializationOperation(BuildWindowMonitorOperation));
|
operations.Enqueue(new LazyInitializationOperation(BuildWindowMonitorOperation));
|
||||||
operations.Enqueue(new LazyInitializationOperation(BuildProcessMonitorOperation));
|
operations.Enqueue(new LazyInitializationOperation(BuildProcessMonitorOperation));
|
||||||
operations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, taskbar));
|
operations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, taskbar));
|
||||||
operations.Enqueue(new LazyInitializationOperation(BuildActionCenterOperation));
|
operations.Enqueue(new LazyInitializationOperation(BuildShellOperation));
|
||||||
operations.Enqueue(new LazyInitializationOperation(BuildTaskbarOperation));
|
|
||||||
operations.Enqueue(new LazyInitializationOperation(BuildBrowserOperation));
|
operations.Enqueue(new LazyInitializationOperation(BuildBrowserOperation));
|
||||||
operations.Enqueue(new ClipboardOperation(logger, nativeMethods));
|
operations.Enqueue(new ClipboardOperation(logger, nativeMethods));
|
||||||
operations.Enqueue(new DelegateOperation(UpdateClientControllerDependencies));
|
operations.Enqueue(new DelegateOperation(UpdateClientControllerDependencies));
|
||||||
|
@ -196,35 +195,6 @@ namespace SafeExamBrowser.Client
|
||||||
textResource = new XmlTextResource(path);
|
textResource = new XmlTextResource(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IOperation BuildActionCenterOperation()
|
|
||||||
{
|
|
||||||
var aboutInfo = new AboutNotificationInfo(text);
|
|
||||||
var aboutController = new AboutNotificationController(configuration.AppConfig, uiFactory);
|
|
||||||
var logInfo = new LogNotificationInfo(text);
|
|
||||||
var logController = new LogNotificationController(logger, uiFactory);
|
|
||||||
var activators = new IActionCenterActivator[]
|
|
||||||
{
|
|
||||||
new KeyboardActivator(new ModuleLogger(logger, nameof(KeyboardActivator))),
|
|
||||||
new TouchActivator(new ModuleLogger(logger, nameof(TouchActivator)))
|
|
||||||
};
|
|
||||||
var operation = new ActionCenterOperation(
|
|
||||||
actionCenter,
|
|
||||||
activators,
|
|
||||||
logger,
|
|
||||||
aboutInfo,
|
|
||||||
aboutController,
|
|
||||||
logInfo,
|
|
||||||
logController,
|
|
||||||
keyboardLayout,
|
|
||||||
powerSupply,
|
|
||||||
wirelessNetwork,
|
|
||||||
configuration.Settings.ActionCenter,
|
|
||||||
systemInfo,
|
|
||||||
uiFactory);
|
|
||||||
|
|
||||||
return operation;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IOperation BuildBrowserOperation()
|
private IOperation BuildBrowserOperation()
|
||||||
{
|
{
|
||||||
var moduleLogger = new ModuleLogger(logger, "BrowserController");
|
var moduleLogger = new ModuleLogger(logger, "BrowserController");
|
||||||
|
@ -280,13 +250,21 @@ namespace SafeExamBrowser.Client
|
||||||
return new ProcessMonitorOperation(logger, processMonitor, configuration.Settings);
|
return new ProcessMonitorOperation(logger, processMonitor, configuration.Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IOperation BuildTaskbarOperation()
|
private IOperation BuildShellOperation()
|
||||||
{
|
{
|
||||||
var aboutInfo = new AboutNotificationInfo(text);
|
var aboutInfo = new AboutNotificationInfo(text);
|
||||||
var aboutController = new AboutNotificationController(configuration.AppConfig, uiFactory);
|
var aboutController = new AboutNotificationController(configuration.AppConfig, uiFactory);
|
||||||
var logInfo = new LogNotificationInfo(text);
|
var logInfo = new LogNotificationInfo(text);
|
||||||
var logController = new LogNotificationController(logger, uiFactory);
|
var logController = new LogNotificationController(logger, uiFactory);
|
||||||
var operation = new TaskbarOperation(
|
var activators = new IActionCenterActivator[]
|
||||||
|
{
|
||||||
|
new KeyboardActivator(new ModuleLogger(logger, nameof(KeyboardActivator))),
|
||||||
|
new TouchActivator(new ModuleLogger(logger, nameof(TouchActivator)))
|
||||||
|
};
|
||||||
|
var operation = new ShellOperation(
|
||||||
|
actionCenter,
|
||||||
|
activators,
|
||||||
|
configuration.Settings.ActionCenter,
|
||||||
logger,
|
logger,
|
||||||
aboutInfo,
|
aboutInfo,
|
||||||
aboutController,
|
aboutController,
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2019 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.Collections.Generic;
|
|
||||||
using SafeExamBrowser.Contracts.Client;
|
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
|
||||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
|
||||||
using SafeExamBrowser.Contracts.Core.OperationModel.Events;
|
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
|
||||||
using SafeExamBrowser.Contracts.SystemComponents;
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface.Shell;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client.Operations
|
|
||||||
{
|
|
||||||
internal class ActionCenterOperation : IOperation
|
|
||||||
{
|
|
||||||
private IActionCenter actionCenter;
|
|
||||||
private IEnumerable<IActionCenterActivator> activators;
|
|
||||||
private ILogger logger;
|
|
||||||
private INotificationInfo aboutInfo;
|
|
||||||
private INotificationController aboutController;
|
|
||||||
private INotificationInfo logInfo;
|
|
||||||
private INotificationController logController;
|
|
||||||
private ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout;
|
|
||||||
private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
|
|
||||||
private ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork;
|
|
||||||
private ActionCenterSettings settings;
|
|
||||||
private ISystemInfo systemInfo;
|
|
||||||
private IUserInterfaceFactory uiFactory;
|
|
||||||
|
|
||||||
public event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
|
||||||
public event StatusChangedEventHandler StatusChanged;
|
|
||||||
|
|
||||||
public ActionCenterOperation(
|
|
||||||
IActionCenter actionCenter,
|
|
||||||
IEnumerable<IActionCenterActivator> activators,
|
|
||||||
ILogger logger,
|
|
||||||
INotificationInfo aboutInfo,
|
|
||||||
INotificationController aboutController,
|
|
||||||
INotificationInfo logInfo,
|
|
||||||
INotificationController logController,
|
|
||||||
ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout,
|
|
||||||
ISystemComponent<ISystemPowerSupplyControl> powerSupply,
|
|
||||||
ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork,
|
|
||||||
ActionCenterSettings settings,
|
|
||||||
ISystemInfo systemInfo,
|
|
||||||
IUserInterfaceFactory uiFactory)
|
|
||||||
{
|
|
||||||
this.actionCenter = actionCenter;
|
|
||||||
this.activators = activators;
|
|
||||||
this.logger = logger;
|
|
||||||
this.aboutInfo = aboutInfo;
|
|
||||||
this.aboutController = aboutController;
|
|
||||||
this.logInfo = logInfo;
|
|
||||||
this.logController = logController;
|
|
||||||
this.keyboardLayout = keyboardLayout;
|
|
||||||
this.powerSupply = powerSupply;
|
|
||||||
this.wirelessNetwork = wirelessNetwork;
|
|
||||||
this.systemInfo = systemInfo;
|
|
||||||
this.settings = settings;
|
|
||||||
this.uiFactory = uiFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationResult Perform()
|
|
||||||
{
|
|
||||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeActionCenter);
|
|
||||||
|
|
||||||
if (settings.EnableActionCenter)
|
|
||||||
{
|
|
||||||
logger.Info("Initializing action center...");
|
|
||||||
|
|
||||||
foreach (var activator in activators)
|
|
||||||
{
|
|
||||||
actionCenter.Register(activator);
|
|
||||||
activator.Start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Info("Action center is disabled, skipping initialization.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return OperationResult.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationResult Revert()
|
|
||||||
{
|
|
||||||
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateActionCenter);
|
|
||||||
|
|
||||||
if (settings.EnableActionCenter)
|
|
||||||
{
|
|
||||||
logger.Info("Terminating action center...");
|
|
||||||
|
|
||||||
foreach (var activator in activators)
|
|
||||||
{
|
|
||||||
activator.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Info("Action center was disabled, skipping termination.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return OperationResult.Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
275
SafeExamBrowser.Client/Operations/ShellOperation.cs
Normal file
275
SafeExamBrowser.Client/Operations/ShellOperation.cs
Normal file
|
@ -0,0 +1,275 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 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.Collections.Generic;
|
||||||
|
using SafeExamBrowser.Contracts.Client;
|
||||||
|
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||||
|
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||||
|
using SafeExamBrowser.Contracts.Core.OperationModel.Events;
|
||||||
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
|
using SafeExamBrowser.Contracts.SystemComponents;
|
||||||
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
using SafeExamBrowser.Contracts.UserInterface.Shell;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.Client.Operations
|
||||||
|
{
|
||||||
|
internal class ShellOperation : IOperation
|
||||||
|
{
|
||||||
|
private IActionCenter actionCenter;
|
||||||
|
private IEnumerable<IActionCenterActivator> activators;
|
||||||
|
private ActionCenterSettings actionCenterSettings;
|
||||||
|
private ILogger logger;
|
||||||
|
private INotificationInfo aboutInfo;
|
||||||
|
private INotificationController aboutController;
|
||||||
|
private INotificationInfo logInfo;
|
||||||
|
private INotificationController logController;
|
||||||
|
private ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout;
|
||||||
|
private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
|
||||||
|
private ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork;
|
||||||
|
private ISystemInfo systemInfo;
|
||||||
|
private ITaskbar taskbar;
|
||||||
|
private TaskbarSettings taskbarSettings;
|
||||||
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
|
public event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||||
|
public event StatusChangedEventHandler StatusChanged;
|
||||||
|
|
||||||
|
public ShellOperation(
|
||||||
|
IActionCenter actionCenter,
|
||||||
|
IEnumerable<IActionCenterActivator> activators,
|
||||||
|
ActionCenterSettings actionCenterSettings,
|
||||||
|
ILogger logger,
|
||||||
|
INotificationInfo aboutInfo,
|
||||||
|
INotificationController aboutController,
|
||||||
|
INotificationInfo logInfo,
|
||||||
|
INotificationController logController,
|
||||||
|
ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout,
|
||||||
|
ISystemComponent<ISystemPowerSupplyControl> powerSupply,
|
||||||
|
ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork,
|
||||||
|
ISystemInfo systemInfo,
|
||||||
|
ITaskbar taskbar,
|
||||||
|
TaskbarSettings taskbarSettings,
|
||||||
|
IUserInterfaceFactory uiFactory)
|
||||||
|
{
|
||||||
|
this.aboutInfo = aboutInfo;
|
||||||
|
this.aboutController = aboutController;
|
||||||
|
this.actionCenter = actionCenter;
|
||||||
|
this.activators = activators;
|
||||||
|
this.actionCenterSettings = actionCenterSettings;
|
||||||
|
this.logger = logger;
|
||||||
|
this.logInfo = logInfo;
|
||||||
|
this.logController = logController;
|
||||||
|
this.keyboardLayout = keyboardLayout;
|
||||||
|
this.powerSupply = powerSupply;
|
||||||
|
this.taskbarSettings = taskbarSettings;
|
||||||
|
this.systemInfo = systemInfo;
|
||||||
|
this.taskbar = taskbar;
|
||||||
|
this.uiFactory = uiFactory;
|
||||||
|
this.wirelessNetwork = wirelessNetwork;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperationResult Perform()
|
||||||
|
{
|
||||||
|
logger.Info("Initializing shell...");
|
||||||
|
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeShell);
|
||||||
|
|
||||||
|
InitializeSystemComponents();
|
||||||
|
InitializeActionCenter();
|
||||||
|
InitializeTaskbar();
|
||||||
|
|
||||||
|
return OperationResult.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperationResult Revert()
|
||||||
|
{
|
||||||
|
logger.Info("Terminating shell...");
|
||||||
|
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateShell);
|
||||||
|
|
||||||
|
TerminateNotifications();
|
||||||
|
TerminateSystemComponents();
|
||||||
|
|
||||||
|
return OperationResult.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeActionCenter()
|
||||||
|
{
|
||||||
|
if (actionCenterSettings.EnableActionCenter)
|
||||||
|
{
|
||||||
|
logger.Info("Initializing action center...");
|
||||||
|
|
||||||
|
InitializeAboutNotificationForActionCenter();
|
||||||
|
InitializeClockForActionCenter();
|
||||||
|
InitializeLogNotificationForActionCenter();
|
||||||
|
InitializeKeyboardLayoutForActionCenter();
|
||||||
|
InitializeWirelessNetworkForActionCenter();
|
||||||
|
InitializePowerSupplyForActionCenter();
|
||||||
|
|
||||||
|
//if (settings.AllowKeyboardLayout)
|
||||||
|
//{
|
||||||
|
// AddKeyboardLayoutControl();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (settings.AllowWirelessNetwork)
|
||||||
|
//{
|
||||||
|
// AddWirelessNetworkControl();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (systemInfo.HasBattery)
|
||||||
|
//{
|
||||||
|
// AddPowerSupplyControl();
|
||||||
|
//}
|
||||||
|
|
||||||
|
foreach (var activator in activators)
|
||||||
|
{
|
||||||
|
actionCenter.Register(activator);
|
||||||
|
activator.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Info("Action center is disabled, skipping initialization.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeTaskbar()
|
||||||
|
{
|
||||||
|
if (taskbarSettings.EnableTaskbar)
|
||||||
|
{
|
||||||
|
logger.Info("Initializing taskbar...");
|
||||||
|
|
||||||
|
InitializeAboutNotificationForTaskbar();
|
||||||
|
InitializeClockForTaskbar();
|
||||||
|
InitializeLogNotificationForTaskbar();
|
||||||
|
InitializeKeyboardLayoutForTaskbar();
|
||||||
|
InitializeWirelessNetworkForTaskbar();
|
||||||
|
InitializePowerSupplyForTaskbar();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Info("Taskbar is disabled, skipping initialization.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeSystemComponents()
|
||||||
|
{
|
||||||
|
keyboardLayout.Initialize();
|
||||||
|
powerSupply.Initialize();
|
||||||
|
wirelessNetwork.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeAboutNotificationForActionCenter()
|
||||||
|
{
|
||||||
|
var notification = uiFactory.CreateNotificationControl(aboutInfo, Location.ActionCenter);
|
||||||
|
|
||||||
|
aboutController.RegisterNotification(notification);
|
||||||
|
actionCenter.AddNotificationControl(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeAboutNotificationForTaskbar()
|
||||||
|
{
|
||||||
|
var notification = uiFactory.CreateNotificationControl(aboutInfo, Location.Taskbar);
|
||||||
|
|
||||||
|
aboutController.RegisterNotification(notification);
|
||||||
|
taskbar.AddNotificationControl(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeClockForActionCenter()
|
||||||
|
{
|
||||||
|
//TODO: actionCenter.ShowClock = settings.ShowClock;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeClockForTaskbar()
|
||||||
|
{
|
||||||
|
taskbar.ShowClock = taskbarSettings.ShowClock;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeLogNotificationForActionCenter()
|
||||||
|
{
|
||||||
|
if (actionCenterSettings.AllowApplicationLog)
|
||||||
|
{
|
||||||
|
var notification = uiFactory.CreateNotificationControl(logInfo, Location.ActionCenter);
|
||||||
|
|
||||||
|
logController.RegisterNotification(notification);
|
||||||
|
actionCenter.AddNotificationControl(notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeLogNotificationForTaskbar()
|
||||||
|
{
|
||||||
|
if (taskbarSettings.AllowApplicationLog)
|
||||||
|
{
|
||||||
|
var notification = uiFactory.CreateNotificationControl(logInfo, Location.Taskbar);
|
||||||
|
|
||||||
|
logController.RegisterNotification(notification);
|
||||||
|
taskbar.AddNotificationControl(notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeKeyboardLayoutForActionCenter()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeKeyboardLayoutForTaskbar()
|
||||||
|
{
|
||||||
|
if (taskbarSettings.AllowKeyboardLayout)
|
||||||
|
{
|
||||||
|
var control = uiFactory.CreateKeyboardLayoutControl();
|
||||||
|
|
||||||
|
keyboardLayout.Register(control);
|
||||||
|
taskbar.AddSystemControl(control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializePowerSupplyForActionCenter()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializePowerSupplyForTaskbar()
|
||||||
|
{
|
||||||
|
if (systemInfo.HasBattery)
|
||||||
|
{
|
||||||
|
var control = uiFactory.CreatePowerSupplyControl();
|
||||||
|
|
||||||
|
powerSupply.Register(control);
|
||||||
|
taskbar.AddSystemControl(control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeWirelessNetworkForActionCenter()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeWirelessNetworkForTaskbar()
|
||||||
|
{
|
||||||
|
if (taskbarSettings.AllowWirelessNetwork)
|
||||||
|
{
|
||||||
|
var control = uiFactory.CreateWirelessNetworkControl();
|
||||||
|
|
||||||
|
wirelessNetwork.Register(control);
|
||||||
|
taskbar.AddSystemControl(control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TerminateNotifications()
|
||||||
|
{
|
||||||
|
aboutController.Terminate();
|
||||||
|
logController.Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TerminateSystemComponents()
|
||||||
|
{
|
||||||
|
keyboardLayout.Terminate();
|
||||||
|
powerSupply.Terminate();
|
||||||
|
wirelessNetwork.Terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,183 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2019 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 SafeExamBrowser.Contracts.Client;
|
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
|
||||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
|
||||||
using SafeExamBrowser.Contracts.Core.OperationModel.Events;
|
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
|
||||||
using SafeExamBrowser.Contracts.SystemComponents;
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface.Shell;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client.Operations
|
|
||||||
{
|
|
||||||
internal class TaskbarOperation : IOperation
|
|
||||||
{
|
|
||||||
private ILogger logger;
|
|
||||||
private INotificationInfo aboutInfo;
|
|
||||||
private INotificationController aboutController;
|
|
||||||
private INotificationInfo logInfo;
|
|
||||||
private INotificationController logController;
|
|
||||||
private TaskbarSettings settings;
|
|
||||||
private ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout;
|
|
||||||
private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
|
|
||||||
private ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork;
|
|
||||||
private ISystemInfo systemInfo;
|
|
||||||
private ITaskbar taskbar;
|
|
||||||
private IUserInterfaceFactory uiFactory;
|
|
||||||
|
|
||||||
public event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
|
||||||
public event StatusChangedEventHandler StatusChanged;
|
|
||||||
|
|
||||||
public TaskbarOperation(
|
|
||||||
ILogger logger,
|
|
||||||
INotificationInfo aboutInfo,
|
|
||||||
INotificationController aboutController,
|
|
||||||
INotificationInfo logInfo,
|
|
||||||
INotificationController logController,
|
|
||||||
ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout,
|
|
||||||
ISystemComponent<ISystemPowerSupplyControl> powerSupply,
|
|
||||||
ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork,
|
|
||||||
ISystemInfo systemInfo,
|
|
||||||
ITaskbar taskbar,
|
|
||||||
TaskbarSettings settings,
|
|
||||||
IUserInterfaceFactory uiFactory)
|
|
||||||
{
|
|
||||||
this.aboutInfo = aboutInfo;
|
|
||||||
this.aboutController = aboutController;
|
|
||||||
this.logger = logger;
|
|
||||||
this.logInfo = logInfo;
|
|
||||||
this.logController = logController;
|
|
||||||
this.keyboardLayout = keyboardLayout;
|
|
||||||
this.powerSupply = powerSupply;
|
|
||||||
this.settings = settings;
|
|
||||||
this.systemInfo = systemInfo;
|
|
||||||
this.taskbar = taskbar;
|
|
||||||
this.uiFactory = uiFactory;
|
|
||||||
this.wirelessNetwork = wirelessNetwork;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationResult Perform()
|
|
||||||
{
|
|
||||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeTaskbar);
|
|
||||||
|
|
||||||
if (settings.EnableTaskbar)
|
|
||||||
{
|
|
||||||
logger.Info("Initializing taskbar...");
|
|
||||||
|
|
||||||
AddAboutNotification();
|
|
||||||
taskbar.ShowClock = settings.ShowClock;
|
|
||||||
|
|
||||||
if (settings.AllowApplicationLog)
|
|
||||||
{
|
|
||||||
AddLogNotification();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.AllowKeyboardLayout)
|
|
||||||
{
|
|
||||||
AddKeyboardLayoutControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.AllowWirelessNetwork)
|
|
||||||
{
|
|
||||||
AddWirelessNetworkControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (systemInfo.HasBattery)
|
|
||||||
{
|
|
||||||
AddPowerSupplyControl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Info("Taskbar is disabled, skipping initialization.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return OperationResult.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationResult Revert()
|
|
||||||
{
|
|
||||||
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateTaskbar);
|
|
||||||
|
|
||||||
if (settings.EnableTaskbar)
|
|
||||||
{
|
|
||||||
logger.Info("Terminating taskbar...");
|
|
||||||
aboutController.Terminate();
|
|
||||||
|
|
||||||
if (settings.AllowApplicationLog)
|
|
||||||
{
|
|
||||||
logController.Terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.AllowKeyboardLayout)
|
|
||||||
{
|
|
||||||
keyboardLayout.Terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.AllowWirelessNetwork)
|
|
||||||
{
|
|
||||||
wirelessNetwork.Terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (systemInfo.HasBattery)
|
|
||||||
{
|
|
||||||
powerSupply.Terminate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Info("Taskbar was disabled, skipping termination.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return OperationResult.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddAboutNotification()
|
|
||||||
{
|
|
||||||
var aboutNotification = uiFactory.CreateNotificationControl(aboutInfo);
|
|
||||||
|
|
||||||
aboutController.RegisterNotification(aboutNotification);
|
|
||||||
taskbar.AddNotificationControl(aboutNotification);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddKeyboardLayoutControl()
|
|
||||||
{
|
|
||||||
var control = uiFactory.CreateKeyboardLayoutControl();
|
|
||||||
|
|
||||||
keyboardLayout.Initialize(control);
|
|
||||||
taskbar.AddSystemControl(control);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddLogNotification()
|
|
||||||
{
|
|
||||||
var logNotification = uiFactory.CreateNotificationControl(logInfo);
|
|
||||||
|
|
||||||
logController.RegisterNotification(logNotification);
|
|
||||||
taskbar.AddNotificationControl(logNotification);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddPowerSupplyControl()
|
|
||||||
{
|
|
||||||
var control = uiFactory.CreatePowerSupplyControl();
|
|
||||||
|
|
||||||
powerSupply.Initialize(control);
|
|
||||||
taskbar.AddSystemControl(control);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddWirelessNetworkControl()
|
|
||||||
{
|
|
||||||
var control = uiFactory.CreateWirelessNetworkControl();
|
|
||||||
|
|
||||||
wirelessNetwork.Initialize(control);
|
|
||||||
taskbar.AddSystemControl(control);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -72,7 +72,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="App.cs" />
|
<Compile Include="App.cs" />
|
||||||
<Compile Include="ClientController.cs" />
|
<Compile Include="ClientController.cs" />
|
||||||
<Compile Include="Operations\ActionCenterOperation.cs" />
|
|
||||||
<Compile Include="Operations\ClientHostDisconnectionOperation.cs" />
|
<Compile Include="Operations\ClientHostDisconnectionOperation.cs" />
|
||||||
<Compile Include="Operations\ConfigurationOperation.cs" />
|
<Compile Include="Operations\ConfigurationOperation.cs" />
|
||||||
<Compile Include="Operations\InitializationOperation.cs" />
|
<Compile Include="Operations\InitializationOperation.cs" />
|
||||||
|
@ -91,7 +90,7 @@
|
||||||
<Compile Include="Operations\KeyboardInterceptorOperation.cs" />
|
<Compile Include="Operations\KeyboardInterceptorOperation.cs" />
|
||||||
<Compile Include="Operations\MouseInterceptorOperation.cs" />
|
<Compile Include="Operations\MouseInterceptorOperation.cs" />
|
||||||
<Compile Include="Operations\ProcessMonitorOperation.cs" />
|
<Compile Include="Operations\ProcessMonitorOperation.cs" />
|
||||||
<Compile Include="Operations\TaskbarOperation.cs" />
|
<Compile Include="Operations\ShellOperation.cs" />
|
||||||
<Compile Include="Operations\WindowMonitorOperation.cs" />
|
<Compile Include="Operations\WindowMonitorOperation.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs">
|
<Compile Include="Properties\AssemblyInfo.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
|
|
|
@ -145,6 +145,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
||||||
settings.Taskbar.ShowClock = true;
|
settings.Taskbar.ShowClock = true;
|
||||||
|
|
||||||
// TODO: Default values for testing of alpha version only, remove for final release!
|
// TODO: Default values for testing of alpha version only, remove for final release!
|
||||||
|
settings.ActionCenter.AllowApplicationLog = true;
|
||||||
settings.Browser.AllowDeveloperConsole = true;
|
settings.Browser.AllowDeveloperConsole = true;
|
||||||
settings.Browser.MainWindowSettings.AllowAddressBar = true;
|
settings.Browser.MainWindowSettings.AllowAddressBar = true;
|
||||||
settings.Taskbar.AllowApplicationLog = true;
|
settings.Taskbar.AllowApplicationLog = true;
|
||||||
|
|
|
@ -16,6 +16,11 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ActionCenterSettings
|
public class ActionCenterSettings
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the user may access the application log during runtime.
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowApplicationLog { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the action center itself is enabled and visible to the user.
|
/// Determines whether the action center itself is enabled and visible to the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -56,7 +56,6 @@ namespace SafeExamBrowser.Contracts.I18n
|
||||||
OperationStatus_CloseRuntimeConnection,
|
OperationStatus_CloseRuntimeConnection,
|
||||||
OperationStatus_EmptyClipboard,
|
OperationStatus_EmptyClipboard,
|
||||||
OperationStatus_FinalizeServiceSession,
|
OperationStatus_FinalizeServiceSession,
|
||||||
OperationStatus_InitializeActionCenter,
|
|
||||||
OperationStatus_InitializeBrowser,
|
OperationStatus_InitializeBrowser,
|
||||||
OperationStatus_InitializeClient,
|
OperationStatus_InitializeClient,
|
||||||
OperationStatus_InitializeConfiguration,
|
OperationStatus_InitializeConfiguration,
|
||||||
|
@ -64,7 +63,7 @@ namespace SafeExamBrowser.Contracts.I18n
|
||||||
OperationStatus_InitializeProcessMonitoring,
|
OperationStatus_InitializeProcessMonitoring,
|
||||||
OperationStatus_InitializeRuntimeConnection,
|
OperationStatus_InitializeRuntimeConnection,
|
||||||
OperationStatus_InitializeServiceSession,
|
OperationStatus_InitializeServiceSession,
|
||||||
OperationStatus_InitializeTaskbar,
|
OperationStatus_InitializeShell,
|
||||||
OperationStatus_InitializeWindowMonitoring,
|
OperationStatus_InitializeWindowMonitoring,
|
||||||
OperationStatus_InitializeWorkingArea,
|
OperationStatus_InitializeWorkingArea,
|
||||||
OperationStatus_RestartCommunicationHost,
|
OperationStatus_RestartCommunicationHost,
|
||||||
|
@ -81,9 +80,8 @@ namespace SafeExamBrowser.Contracts.I18n
|
||||||
OperationStatus_StopMouseInterception,
|
OperationStatus_StopMouseInterception,
|
||||||
OperationStatus_StopProcessMonitoring,
|
OperationStatus_StopProcessMonitoring,
|
||||||
OperationStatus_StopWindowMonitoring,
|
OperationStatus_StopWindowMonitoring,
|
||||||
OperationStatus_TerminateActionCenter,
|
|
||||||
OperationStatus_TerminateBrowser,
|
OperationStatus_TerminateBrowser,
|
||||||
OperationStatus_TerminateTaskbar,
|
OperationStatus_TerminateShell,
|
||||||
OperationStatus_WaitExplorerStartup,
|
OperationStatus_WaitExplorerStartup,
|
||||||
OperationStatus_WaitExplorerTermination,
|
OperationStatus_WaitExplorerTermination,
|
||||||
OperationStatus_WaitRuntimeDisconnection,
|
OperationStatus_WaitRuntimeDisconnection,
|
||||||
|
|
|
@ -17,9 +17,14 @@ namespace SafeExamBrowser.Contracts.SystemComponents
|
||||||
public interface ISystemComponent<TControl> where TControl : ISystemControl
|
public interface ISystemComponent<TControl> where TControl : ISystemControl
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the resources and operations of the component and registers its taskbar control.
|
/// Initializes the resources and operations of the component.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Initialize(TControl control);
|
void Initialize();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a system control which will be loaded into shell.
|
||||||
|
/// </summary>
|
||||||
|
void Register(TControl control);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instructs the component to stop any running operations and releases all used resources.
|
/// Instructs the component to stop any running operations and releases all used resources.
|
||||||
|
|
|
@ -51,9 +51,9 @@ namespace SafeExamBrowser.Contracts.UserInterface
|
||||||
IWindow CreateLogWindow(ILogger logger);
|
IWindow CreateLogWindow(ILogger logger);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a notification control, initialized with the given notification information.
|
/// Creates a notification control for the specified location, initialized with the given notification information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
INotificationControl CreateNotificationControl(INotificationInfo info);
|
INotificationControl CreateNotificationControl(INotificationInfo info, Location location);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a password dialog with the given message and title.
|
/// Creates a password dialog with the given message and title.
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
namespace SafeExamBrowser.Contracts.UserInterface.Shell
|
namespace SafeExamBrowser.Contracts.UserInterface.Shell
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The control of a system component which can be loaded into the <see cref="ITaskbar"/>.
|
/// The control of a system component which can be loaded into the shell.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISystemControl
|
public interface ISystemControl
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Closes any pop-up windows associated with this control.
|
/// Closes the control and / or any associated user interface elements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
|
|
|
@ -126,9 +126,6 @@
|
||||||
<Entry key="OperationStatus_FinalizeServiceSession">
|
<Entry key="OperationStatus_FinalizeServiceSession">
|
||||||
Finalizing service session
|
Finalizing service session
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="OperationStatus_InitializeActionCenter">
|
|
||||||
Initializing action center
|
|
||||||
</Entry>
|
|
||||||
<Entry key="OperationStatus_InitializeBrowser">
|
<Entry key="OperationStatus_InitializeBrowser">
|
||||||
Initializing browser
|
Initializing browser
|
||||||
</Entry>
|
</Entry>
|
||||||
|
@ -153,8 +150,8 @@
|
||||||
<Entry key="OperationStatus_InitializeSession">
|
<Entry key="OperationStatus_InitializeSession">
|
||||||
Initializing new session
|
Initializing new session
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="OperationStatus_InitializeTaskbar">
|
<Entry key="OperationStatus_InitializeShell">
|
||||||
Initializing taskbar
|
Initializing user interface
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="OperationStatus_InitializeWindowMonitoring">
|
<Entry key="OperationStatus_InitializeWindowMonitoring">
|
||||||
Initializing window monitoring
|
Initializing window monitoring
|
||||||
|
@ -201,14 +198,11 @@
|
||||||
<Entry key="OperationStatus_StopWindowMonitoring">
|
<Entry key="OperationStatus_StopWindowMonitoring">
|
||||||
Stopping window monitoring
|
Stopping window monitoring
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="OperationStatus_TerminateActionCenter">
|
|
||||||
Terminating action center
|
|
||||||
</Entry>
|
|
||||||
<Entry key="OperationStatus_TerminateBrowser">
|
<Entry key="OperationStatus_TerminateBrowser">
|
||||||
Terminating browser
|
Terminating browser
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="OperationStatus_TerminateTaskbar">
|
<Entry key="OperationStatus_TerminateShell">
|
||||||
Terminating taskbar
|
Terminating user interface
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="OperationStatus_WaitExplorerStartup">
|
<Entry key="OperationStatus_WaitExplorerStartup">
|
||||||
Waiting for Windows explorer to start up
|
Waiting for Windows explorer to start up
|
||||||
|
|
|
@ -21,23 +21,19 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
private IList<KeyboardLayoutDefinition> layouts = new List<KeyboardLayoutDefinition>();
|
private IList<KeyboardLayoutDefinition> layouts = new List<KeyboardLayoutDefinition>();
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private InputLanguage originalLanguage;
|
private InputLanguage originalLanguage;
|
||||||
private ISystemKeyboardLayoutControl control;
|
private IList<ISystemKeyboardLayoutControl> controls;
|
||||||
private IText text;
|
private IText text;
|
||||||
|
|
||||||
public KeyboardLayout(ILogger logger, IText text)
|
public KeyboardLayout(ILogger logger, IText text)
|
||||||
{
|
{
|
||||||
|
this.controls = new List<ISystemKeyboardLayoutControl>();
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(ISystemKeyboardLayoutControl control)
|
public void Initialize()
|
||||||
{
|
{
|
||||||
this.control = control;
|
|
||||||
|
|
||||||
originalLanguage = InputLanguage.CurrentInputLanguage;
|
originalLanguage = InputLanguage.CurrentInputLanguage;
|
||||||
control.LayoutSelected += Control_LayoutSelected;
|
|
||||||
control.SetTooltip(text.Get(TextKey.SystemControl_KeyboardLayoutTooltip));
|
|
||||||
|
|
||||||
logger.Info($"Saved current keyboard layout {ToString(originalLanguage)}.");
|
logger.Info($"Saved current keyboard layout {ToString(originalLanguage)}.");
|
||||||
|
|
||||||
foreach (InputLanguage language in InputLanguage.InstalledInputLanguages)
|
foreach (InputLanguage language in InputLanguage.InstalledInputLanguages)
|
||||||
|
@ -50,22 +46,36 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
Name = language.LayoutName
|
Name = language.LayoutName
|
||||||
};
|
};
|
||||||
|
|
||||||
control.Add(layout);
|
|
||||||
layouts.Add(layout);
|
layouts.Add(layout);
|
||||||
|
logger.Info($"Detected keyboard layout {ToString(language)}.");
|
||||||
logger.Info($"Added keyboard layout {ToString(language)} to system control.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Register(ISystemKeyboardLayoutControl control)
|
||||||
|
{
|
||||||
|
control.LayoutSelected += Control_LayoutSelected;
|
||||||
|
control.SetTooltip(text.Get(TextKey.SystemControl_KeyboardLayoutTooltip));
|
||||||
|
|
||||||
|
foreach (var layout in layouts)
|
||||||
|
{
|
||||||
|
control.Add(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.Add(control);
|
||||||
|
}
|
||||||
|
|
||||||
public void Terminate()
|
public void Terminate()
|
||||||
{
|
{
|
||||||
control?.Close();
|
|
||||||
|
|
||||||
if (originalLanguage != null)
|
if (originalLanguage != null)
|
||||||
{
|
{
|
||||||
InputLanguage.CurrentInputLanguage = originalLanguage;
|
InputLanguage.CurrentInputLanguage = originalLanguage;
|
||||||
logger.Info($"Restored original keyboard layout {ToString(originalLanguage)}.");
|
logger.Info($"Restored original keyboard layout {ToString(originalLanguage)}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var control in controls)
|
||||||
|
{
|
||||||
|
control.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Control_LayoutSelected(IKeyboardLayout layout)
|
private void Control_LayoutSelected(IKeyboardLayout layout)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
|
@ -23,22 +24,19 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
|
|
||||||
private bool infoShown, warningShown;
|
private bool infoShown, warningShown;
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private ISystemPowerSupplyControl control;
|
private IList<ISystemPowerSupplyControl> controls;
|
||||||
private IText text;
|
private IText text;
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
|
|
||||||
public PowerSupply(ILogger logger, IText text)
|
public PowerSupply(ILogger logger, IText text)
|
||||||
{
|
{
|
||||||
|
this.controls = new List<ISystemPowerSupplyControl>();
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(ISystemPowerSupplyControl control)
|
public void Initialize()
|
||||||
{
|
{
|
||||||
this.control = control;
|
|
||||||
|
|
||||||
UpdateControl();
|
|
||||||
|
|
||||||
timer = new Timer(TWO_SECONDS);
|
timer = new Timer(TWO_SECONDS);
|
||||||
timer.Elapsed += Timer_Elapsed;
|
timer.Elapsed += Timer_Elapsed;
|
||||||
timer.AutoReset = true;
|
timer.AutoReset = true;
|
||||||
|
@ -47,19 +45,32 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
logger.Info("Started monitoring the power supply.");
|
logger.Info("Started monitoring the power supply.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Register(ISystemPowerSupplyControl control)
|
||||||
|
{
|
||||||
|
controls.Add(control);
|
||||||
|
UpdateControls();
|
||||||
|
}
|
||||||
|
|
||||||
public void Terminate()
|
public void Terminate()
|
||||||
{
|
{
|
||||||
timer?.Stop();
|
if (timer != null)
|
||||||
control?.Close();
|
{
|
||||||
logger.Info("Stopped monitoring the power supply.");
|
timer.Stop();
|
||||||
|
logger.Info("Stopped monitoring the power supply.");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var control in controls)
|
||||||
|
{
|
||||||
|
control.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
UpdateControl();
|
UpdateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateControl()
|
private void UpdateControls()
|
||||||
{
|
{
|
||||||
var charge = SystemInformation.PowerStatus.BatteryLifePercent;
|
var charge = SystemInformation.PowerStatus.BatteryLifePercent;
|
||||||
var percentage = Math.Round(charge * 100);
|
var percentage = Math.Round(charge * 100);
|
||||||
|
@ -67,32 +78,35 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
var online = SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online;
|
var online = SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online;
|
||||||
var tooltip = string.Empty;
|
var tooltip = string.Empty;
|
||||||
|
|
||||||
if (online)
|
foreach (var control in controls)
|
||||||
{
|
{
|
||||||
tooltip = text.Get(percentage == 100 ? TextKey.SystemControl_BatteryCharged : TextKey.SystemControl_BatteryCharging);
|
if (online)
|
||||||
infoShown = false;
|
{
|
||||||
warningShown = false;
|
tooltip = text.Get(percentage == 100 ? TextKey.SystemControl_BatteryCharged : TextKey.SystemControl_BatteryCharging);
|
||||||
|
infoShown = false;
|
||||||
|
warningShown = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var hours = SystemInformation.PowerStatus.BatteryLifeRemaining / 3600;
|
||||||
|
var minutes = (SystemInformation.PowerStatus.BatteryLifeRemaining - (hours * 3600)) / 60;
|
||||||
|
|
||||||
|
HandleBatteryStatus(control, status);
|
||||||
|
|
||||||
|
tooltip = text.Get(TextKey.SystemControl_BatteryRemainingCharge);
|
||||||
|
tooltip = tooltip.Replace("%%HOURS%%", hours.ToString());
|
||||||
|
tooltip = tooltip.Replace("%%MINUTES%%", minutes.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip = tooltip.Replace("%%CHARGE%%", percentage.ToString());
|
||||||
|
|
||||||
|
control.SetBatteryCharge(charge, status);
|
||||||
|
control.SetPowerGridConnection(online);
|
||||||
|
control.SetTooltip(tooltip);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
var hours = SystemInformation.PowerStatus.BatteryLifeRemaining / 3600;
|
|
||||||
var minutes = (SystemInformation.PowerStatus.BatteryLifeRemaining - (hours * 3600)) / 60;
|
|
||||||
|
|
||||||
HandleBatteryStatus(status);
|
|
||||||
|
|
||||||
tooltip = text.Get(TextKey.SystemControl_BatteryRemainingCharge);
|
|
||||||
tooltip = tooltip.Replace("%%HOURS%%", hours.ToString());
|
|
||||||
tooltip = tooltip.Replace("%%MINUTES%%", minutes.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltip = tooltip.Replace("%%CHARGE%%", percentage.ToString());
|
|
||||||
|
|
||||||
control.SetBatteryCharge(charge, status);
|
|
||||||
control.SetPowerGridConnection(online);
|
|
||||||
control.SetTooltip(tooltip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleBatteryStatus(BatteryChargeStatus status)
|
private void HandleBatteryStatus(ISystemPowerSupplyControl control, BatteryChargeStatus status)
|
||||||
{
|
{
|
||||||
if (status == BatteryChargeStatus.Low && !infoShown)
|
if (status == BatteryChargeStatus.Low && !infoShown)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,38 +25,30 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
private const int TWO_SECONDS = 2000;
|
private const int TWO_SECONDS = 2000;
|
||||||
private readonly object @lock = new object();
|
private readonly object @lock = new object();
|
||||||
|
|
||||||
private ISystemWirelessNetworkControl control;
|
private IList<ISystemWirelessNetworkControl> controls;
|
||||||
|
private IList<WirelessNetworkDefinition> networks;
|
||||||
|
private bool hasWifiAdapter;
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IList<WirelessNetworkDefinition> networks = new List<WirelessNetworkDefinition>();
|
|
||||||
private IText text;
|
private IText text;
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
private Wifi wifi;
|
private Wifi wifi;
|
||||||
|
|
||||||
public WirelessNetwork(ILogger logger, IText text)
|
public WirelessNetwork(ILogger logger, IText text)
|
||||||
{
|
{
|
||||||
|
this.controls = new List<ISystemWirelessNetworkControl>();
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
this.networks = new List<WirelessNetworkDefinition>();
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(ISystemWirelessNetworkControl control)
|
public void Initialize()
|
||||||
{
|
{
|
||||||
this.control = control;
|
wifi = new Wifi();
|
||||||
this.wifi = new Wifi();
|
wifi.ConnectionStatusChanged += Wifi_ConnectionStatusChanged;
|
||||||
|
hasWifiAdapter = !wifi.NoWifiAvailable && !IsTurnedOff();
|
||||||
|
|
||||||
if (wifi.NoWifiAvailable || IsTurnedOff())
|
if (hasWifiAdapter)
|
||||||
{
|
{
|
||||||
control.HasWirelessNetworkAdapter = false;
|
|
||||||
control.SetTooltip(text.Get(TextKey.SystemControl_WirelessNotAvailable));
|
|
||||||
logger.Info("Wireless networks cannot be monitored, as there is no hardware adapter available or it is turned off.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
control.HasWirelessNetworkAdapter = true;
|
|
||||||
control.NetworkSelected += Control_NetworkSelected;
|
|
||||||
wifi.ConnectionStatusChanged += Wifi_ConnectionStatusChanged;
|
|
||||||
|
|
||||||
UpdateControl();
|
|
||||||
|
|
||||||
timer = new Timer(TWO_SECONDS);
|
timer = new Timer(TWO_SECONDS);
|
||||||
timer.Elapsed += Timer_Elapsed;
|
timer.Elapsed += Timer_Elapsed;
|
||||||
timer.AutoReset = true;
|
timer.AutoReset = true;
|
||||||
|
@ -64,17 +56,45 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
|
|
||||||
logger.Info("Started monitoring the wireless network adapter.");
|
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 Register(ISystemWirelessNetworkControl control)
|
||||||
|
{
|
||||||
|
if (hasWifiAdapter)
|
||||||
|
{
|
||||||
|
control.HasWirelessNetworkAdapter = true;
|
||||||
|
control.NetworkSelected += Control_NetworkSelected;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
control.HasWirelessNetworkAdapter = false;
|
||||||
|
control.SetTooltip(text.Get(TextKey.SystemControl_WirelessNotAvailable));
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.Add(control);
|
||||||
|
|
||||||
|
if (hasWifiAdapter)
|
||||||
|
{
|
||||||
|
UpdateControls();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Terminate()
|
public void Terminate()
|
||||||
{
|
{
|
||||||
timer?.Stop();
|
|
||||||
control?.Close();
|
|
||||||
|
|
||||||
if (timer != null)
|
if (timer != null)
|
||||||
{
|
{
|
||||||
|
timer.Stop();
|
||||||
logger.Info("Stopped monitoring the wireless network adapter.");
|
logger.Info("Stopped monitoring the wireless network adapter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var control in controls)
|
||||||
|
{
|
||||||
|
control.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Control_NetworkSelected(IWirelessNetwork network)
|
private void Control_NetworkSelected(IWirelessNetwork network)
|
||||||
|
@ -85,7 +105,11 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
var authRequest = new AuthRequest(accessPoint);
|
var authRequest = new AuthRequest(accessPoint);
|
||||||
|
|
||||||
accessPoint.ConnectAsync(authRequest, false, (success) => AccessPoint_OnConnectComplete(network.Name, success));
|
accessPoint.ConnectAsync(authRequest, false, (success) => AccessPoint_OnConnectComplete(network.Name, success));
|
||||||
control.IsConnecting = true;
|
|
||||||
|
foreach (var control in controls)
|
||||||
|
{
|
||||||
|
control.IsConnecting = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -104,18 +128,22 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
logger.Error($"Failed to connect to wireless network '{name}!'");
|
logger.Error($"Failed to connect to wireless network '{name}!'");
|
||||||
}
|
}
|
||||||
|
|
||||||
control.IsConnecting = false;
|
foreach (var control in controls)
|
||||||
UpdateControl();
|
{
|
||||||
|
control.IsConnecting = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
UpdateControl();
|
UpdateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Wifi_ConnectionStatusChanged(object sender, WifiStatusEventArgs e)
|
private void Wifi_ConnectionStatusChanged(object sender, WifiStatusEventArgs e)
|
||||||
{
|
{
|
||||||
UpdateControl();
|
UpdateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsTurnedOff()
|
private bool IsTurnedOff()
|
||||||
|
@ -143,12 +171,15 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateControl()
|
private void UpdateControls()
|
||||||
{
|
{
|
||||||
lock (@lock)
|
lock (@lock)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var isConnected = false;
|
||||||
|
var networkName = string.Empty;
|
||||||
|
|
||||||
networks.Clear();
|
networks.Clear();
|
||||||
|
|
||||||
foreach (var accessPoint in wifi.GetAccessPoints())
|
foreach (var accessPoint in wifi.GetAccessPoints())
|
||||||
|
@ -156,22 +187,28 @@ namespace SafeExamBrowser.SystemComponents
|
||||||
// The user may only connect to an already configured wireless network!
|
// The user may only connect to an already configured wireless network!
|
||||||
if (accessPoint.HasProfile)
|
if (accessPoint.HasProfile)
|
||||||
{
|
{
|
||||||
networks.Add(ToDefinition(accessPoint));
|
networkName = accessPoint.Name;
|
||||||
|
isConnected = accessPoint.IsConnected;
|
||||||
|
|
||||||
if (accessPoint.IsConnected)
|
networks.Add(ToDefinition(accessPoint));
|
||||||
{
|
|
||||||
control.SetTooltip(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", accessPoint.Name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wifi.ConnectionStatus == WifiStatus.Disconnected)
|
foreach (var control in controls)
|
||||||
{
|
{
|
||||||
control.SetTooltip(text.Get(TextKey.SystemControl_WirelessDisconnected));
|
if (wifi.ConnectionStatus == WifiStatus.Disconnected)
|
||||||
}
|
{
|
||||||
|
control.SetTooltip(text.Get(TextKey.SystemControl_WirelessDisconnected));
|
||||||
|
}
|
||||||
|
|
||||||
control.NetworkStatus = ToStatus(wifi.ConnectionStatus);
|
if (isConnected)
|
||||||
control.Update(new List<IWirelessNetwork>(networks));
|
{
|
||||||
|
control.SetTooltip(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", networkName));
|
||||||
|
}
|
||||||
|
|
||||||
|
control.NetworkStatus = ToStatus(wifi.ConnectionStatus);
|
||||||
|
control.Update(new List<IWirelessNetwork>(networks));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,14 +20,6 @@
|
||||||
<ScrollViewer Grid.Row="0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
<ScrollViewer Grid.Row="0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
||||||
<StackPanel x:Name="ApplicationPanel" Orientation="Vertical" />
|
<StackPanel x:Name="ApplicationPanel" Orientation="Vertical" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
<UniformGrid x:Name="ControlPanel" Grid.Row="1" Columns="4" Margin="5">
|
<UniformGrid x:Name="ControlPanel" Grid.Row="1" Columns="4" Margin="5" />
|
||||||
<Label Height="60">Control</Label>
|
|
||||||
<Label Height="60">Control</Label>
|
|
||||||
<Label Height="60">Control</Label>
|
|
||||||
<Label Height="60">Control</Label>
|
|
||||||
<Label Height="60">Control</Label>
|
|
||||||
<Label Height="60">Control</Label>
|
|
||||||
<Label Height="60">Control</Label>
|
|
||||||
</UniformGrid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|
|
@ -33,12 +33,18 @@ namespace SafeExamBrowser.UserInterface.Desktop
|
||||||
|
|
||||||
public void AddNotificationControl(INotificationControl control)
|
public void AddNotificationControl(INotificationControl control)
|
||||||
{
|
{
|
||||||
|
if (control is UIElement uiElement)
|
||||||
|
{
|
||||||
|
ControlPanel.Children.Add(uiElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddSystemControl(ISystemControl control)
|
public void AddSystemControl(ISystemControl control)
|
||||||
{
|
{
|
||||||
|
if (control is UIElement uiElement)
|
||||||
|
{
|
||||||
|
ControlPanel.Children.Add(uiElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public new void Close()
|
public new void Close()
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenterNotificationButton"
|
||||||
|
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"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Controls"
|
||||||
|
mc:Ignorable="d" d:DesignHeight="60" d:DesignWidth="80">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary Source="../Templates/Buttons.xaml" />
|
||||||
|
<ResourceDictionary Source="../Templates/Colors.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Grid Background="#AA808080" Margin="5">
|
||||||
|
<Button x:Name="IconButton" Click="Icon_Click" Padding="2" Template="{StaticResource ActionCenterButton}">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="2*" />
|
||||||
|
<RowDefinition Height="1*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<ContentControl Grid.Row="0" x:Name="Icon" Margin="0,5,0,10" MaxHeight="25" />
|
||||||
|
<TextBlock Grid.Row="1" x:Name="Text" FontSize="11" Foreground="White" TextAlignment="Left" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap" />
|
||||||
|
</Grid>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 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.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using SafeExamBrowser.Contracts.Client;
|
||||||
|
using SafeExamBrowser.Contracts.UserInterface.Shell;
|
||||||
|
using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
|
||||||
|
using SafeExamBrowser.UserInterface.Desktop.Utilities;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
|
{
|
||||||
|
public partial class ActionCenterNotificationButton : UserControl, INotificationControl
|
||||||
|
{
|
||||||
|
public event NotificationControlClickedEventHandler Clicked;
|
||||||
|
|
||||||
|
public ActionCenterNotificationButton(INotificationInfo info)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
InitializeNotificationIcon(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Icon_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Clicked?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeNotificationIcon(INotificationInfo info)
|
||||||
|
{
|
||||||
|
Icon.Content = IconResourceLoader.Load(info.IconResource);
|
||||||
|
IconButton.ToolTip = info.Tooltip;
|
||||||
|
Text.Text = info.Tooltip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.NotificationButton"
|
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.TaskbarNotificationButton"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
@ -15,11 +15,11 @@ using SafeExamBrowser.UserInterface.Desktop.Utilities;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||||
{
|
{
|
||||||
public partial class NotificationButton : UserControl, INotificationControl
|
public partial class TaskbarNotificationButton : UserControl, INotificationControl
|
||||||
{
|
{
|
||||||
public event NotificationControlClickedEventHandler Clicked;
|
public event NotificationControlClickedEventHandler Clicked;
|
||||||
|
|
||||||
public NotificationButton(INotificationInfo info)
|
public TaskbarNotificationButton(INotificationInfo info)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeNotificationIcon(info);
|
InitializeNotificationIcon(info);
|
|
@ -80,6 +80,9 @@
|
||||||
<Compile Include="Controls\ActionCenterApplicationButton.xaml.cs">
|
<Compile Include="Controls\ActionCenterApplicationButton.xaml.cs">
|
||||||
<DependentUpon>ActionCenterApplicationButton.xaml</DependentUpon>
|
<DependentUpon>ActionCenterApplicationButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Controls\ActionCenterNotificationButton.xaml.cs">
|
||||||
|
<DependentUpon>ActionCenterNotificationButton.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Controls\TaskbarApplicationControl.xaml.cs">
|
<Compile Include="Controls\TaskbarApplicationControl.xaml.cs">
|
||||||
<DependentUpon>TaskbarApplicationControl.xaml</DependentUpon>
|
<DependentUpon>TaskbarApplicationControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -95,8 +98,8 @@
|
||||||
<Compile Include="Controls\KeyboardLayoutControl.xaml.cs">
|
<Compile Include="Controls\KeyboardLayoutControl.xaml.cs">
|
||||||
<DependentUpon>KeyboardLayoutControl.xaml</DependentUpon>
|
<DependentUpon>KeyboardLayoutControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\NotificationButton.xaml.cs">
|
<Compile Include="Controls\TaskbarNotificationButton.xaml.cs">
|
||||||
<DependentUpon>NotificationButton.xaml</DependentUpon>
|
<DependentUpon>TaskbarNotificationButton.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\PowerSupplyControl.xaml.cs">
|
<Compile Include="Controls\PowerSupplyControl.xaml.cs">
|
||||||
<DependentUpon>PowerSupplyControl.xaml</DependentUpon>
|
<DependentUpon>PowerSupplyControl.xaml</DependentUpon>
|
||||||
|
@ -151,6 +154,10 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Controls\ActionCenterNotificationButton.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Controls\TaskbarApplicationControl.xaml">
|
<Page Include="Controls\TaskbarApplicationControl.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
@ -171,7 +178,7 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="Controls\NotificationButton.xaml">
|
<Page Include="Controls\TaskbarNotificationButton.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
@ -86,9 +86,16 @@ namespace SafeExamBrowser.UserInterface.Desktop
|
||||||
return logWindow;
|
return logWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public INotificationControl CreateNotificationControl(INotificationInfo info)
|
public INotificationControl CreateNotificationControl(INotificationInfo info, Location location)
|
||||||
{
|
{
|
||||||
return new NotificationButton(info);
|
if (location == Location.ActionCenter)
|
||||||
|
{
|
||||||
|
return new ActionCenterNotificationButton(info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new TaskbarNotificationButton(info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IPasswordDialog CreatePasswordDialog(string message, string title)
|
public IPasswordDialog CreatePasswordDialog(string message, string title)
|
||||||
|
|
Loading…
Reference in a new issue