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]
|
||||
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();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -61,7 +56,6 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
public void MustRevertCorrectly()
|
||||
{
|
||||
sut.Revert();
|
||||
|
||||
controller.Verify(c => c.Terminate(), Times.Once);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Client.Operations;
|
||||
|
@ -19,10 +20,13 @@ using SafeExamBrowser.Contracts.UserInterface.Shell;
|
|||
namespace SafeExamBrowser.Client.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class TaskbarOperationTests
|
||||
public class ShellOperationTests
|
||||
{
|
||||
private Mock<IActionCenter> actionCenter;
|
||||
private Mock<IEnumerable<IActionCenterActivator>> activators;
|
||||
private ActionCenterSettings actionCenterSettings;
|
||||
private Mock<ILogger> loggerMock;
|
||||
private TaskbarSettings settings;
|
||||
private TaskbarSettings taskbarSettings;
|
||||
private Mock<INotificationInfo> aboutInfoMock;
|
||||
private Mock<INotificationController> aboutControllerMock;
|
||||
private Mock<INotificationInfo> logInfoMock;
|
||||
|
@ -34,11 +38,14 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
private Mock<ITaskbar> taskbarMock;
|
||||
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
||||
|
||||
private TaskbarOperation sut;
|
||||
private ShellOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
actionCenter = new Mock<IActionCenter>();
|
||||
activators = new Mock<IEnumerable<IActionCenterActivator>>();
|
||||
actionCenterSettings = new ActionCenterSettings();
|
||||
loggerMock = new Mock<ILogger>();
|
||||
aboutInfoMock = new Mock<INotificationInfo>();
|
||||
aboutControllerMock = new Mock<INotificationController>();
|
||||
|
@ -49,17 +56,20 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
wirelessNetworkMock = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
|
||||
systemInfoMock = new Mock<ISystemInfo>();
|
||||
taskbarMock = new Mock<ITaskbar>();
|
||||
settings = new TaskbarSettings();
|
||||
taskbarSettings = new TaskbarSettings();
|
||||
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
||||
|
||||
settings.AllowApplicationLog = true;
|
||||
settings.AllowKeyboardLayout = true;
|
||||
settings.AllowWirelessNetwork = true;
|
||||
settings.EnableTaskbar = true;
|
||||
taskbarSettings.AllowApplicationLog = true;
|
||||
taskbarSettings.AllowKeyboardLayout = true;
|
||||
taskbarSettings.AllowWirelessNetwork = true;
|
||||
taskbarSettings.EnableTaskbar = 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,
|
||||
aboutInfoMock.Object,
|
||||
aboutControllerMock.Object,
|
||||
|
@ -70,7 +80,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
wirelessNetworkMock.Object,
|
||||
systemInfoMock.Object,
|
||||
taskbarMock.Object,
|
||||
settings,
|
||||
taskbarSettings,
|
||||
uiFactoryMock.Object);
|
||||
}
|
||||
|
||||
|
@ -79,9 +89,9 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
{
|
||||
sut.Perform();
|
||||
|
||||
keyboardLayoutMock.Verify(k => k.Initialize(It.IsAny<ISystemKeyboardLayoutControl>()), Times.Once);
|
||||
powerSupplyMock.Verify(p => p.Initialize(It.IsAny<ISystemPowerSupplyControl>()), Times.Once);
|
||||
wirelessNetworkMock.Verify(w => w.Initialize(It.IsAny<ISystemWirelessNetworkControl>()), Times.Once);
|
||||
keyboardLayoutMock.Verify(k => k.Initialize(), Times.Once);
|
||||
powerSupplyMock.Verify(p => p.Initialize(), Times.Once);
|
||||
wirelessNetworkMock.Verify(w => w.Initialize(), Times.Once);
|
||||
taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(3));
|
||||
taskbarMock.Verify(t => t.AddNotificationControl(It.IsAny<INotificationControl>()), Times.Exactly(2));
|
||||
}
|
|
@ -90,7 +90,7 @@
|
|||
<Compile Include="Operations\MouseInterceptorOperationTests.cs" />
|
||||
<Compile Include="Operations\ProcessMonitorOperationTests.cs" />
|
||||
<Compile Include="Operations\RuntimeConnectionOperationTests.cs" />
|
||||
<Compile Include="Operations\TaskbarOperationTests.cs" />
|
||||
<Compile Include="Operations\ShellOperationTests.cs" />
|
||||
<Compile Include="Operations\WindowMonitorOperationTests.cs" />
|
||||
<Compile Include="Communication\ClientHostTests.cs" />
|
||||
<Compile Include="Notifications\AboutNotificationControllerTests.cs" />
|
||||
|
|
|
@ -116,8 +116,7 @@ namespace SafeExamBrowser.Client
|
|||
operations.Enqueue(new LazyInitializationOperation(BuildWindowMonitorOperation));
|
||||
operations.Enqueue(new LazyInitializationOperation(BuildProcessMonitorOperation));
|
||||
operations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, taskbar));
|
||||
operations.Enqueue(new LazyInitializationOperation(BuildActionCenterOperation));
|
||||
operations.Enqueue(new LazyInitializationOperation(BuildTaskbarOperation));
|
||||
operations.Enqueue(new LazyInitializationOperation(BuildShellOperation));
|
||||
operations.Enqueue(new LazyInitializationOperation(BuildBrowserOperation));
|
||||
operations.Enqueue(new ClipboardOperation(logger, nativeMethods));
|
||||
operations.Enqueue(new DelegateOperation(UpdateClientControllerDependencies));
|
||||
|
@ -196,35 +195,6 @@ namespace SafeExamBrowser.Client
|
|||
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()
|
||||
{
|
||||
var moduleLogger = new ModuleLogger(logger, "BrowserController");
|
||||
|
@ -280,13 +250,21 @@ namespace SafeExamBrowser.Client
|
|||
return new ProcessMonitorOperation(logger, processMonitor, configuration.Settings);
|
||||
}
|
||||
|
||||
private IOperation BuildTaskbarOperation()
|
||||
private IOperation BuildShellOperation()
|
||||
{
|
||||
var aboutInfo = new AboutNotificationInfo(text);
|
||||
var aboutController = new AboutNotificationController(configuration.AppConfig, uiFactory);
|
||||
var logInfo = new LogNotificationInfo(text);
|
||||
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,
|
||||
aboutInfo,
|
||||
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>
|
||||
<Compile Include="App.cs" />
|
||||
<Compile Include="ClientController.cs" />
|
||||
<Compile Include="Operations\ActionCenterOperation.cs" />
|
||||
<Compile Include="Operations\ClientHostDisconnectionOperation.cs" />
|
||||
<Compile Include="Operations\ConfigurationOperation.cs" />
|
||||
<Compile Include="Operations\InitializationOperation.cs" />
|
||||
|
@ -91,7 +90,7 @@
|
|||
<Compile Include="Operations\KeyboardInterceptorOperation.cs" />
|
||||
<Compile Include="Operations\MouseInterceptorOperation.cs" />
|
||||
<Compile Include="Operations\ProcessMonitorOperation.cs" />
|
||||
<Compile Include="Operations\TaskbarOperation.cs" />
|
||||
<Compile Include="Operations\ShellOperation.cs" />
|
||||
<Compile Include="Operations\WindowMonitorOperation.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
|
|
|
@ -145,6 +145,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
settings.Taskbar.ShowClock = true;
|
||||
|
||||
// TODO: Default values for testing of alpha version only, remove for final release!
|
||||
settings.ActionCenter.AllowApplicationLog = true;
|
||||
settings.Browser.AllowDeveloperConsole = true;
|
||||
settings.Browser.MainWindowSettings.AllowAddressBar = true;
|
||||
settings.Taskbar.AllowApplicationLog = true;
|
||||
|
|
|
@ -16,6 +16,11 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
|
|||
[Serializable]
|
||||
public class ActionCenterSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the user may access the application log during runtime.
|
||||
/// </summary>
|
||||
public bool AllowApplicationLog { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the action center itself is enabled and visible to the user.
|
||||
/// </summary>
|
||||
|
|
|
@ -56,7 +56,6 @@ namespace SafeExamBrowser.Contracts.I18n
|
|||
OperationStatus_CloseRuntimeConnection,
|
||||
OperationStatus_EmptyClipboard,
|
||||
OperationStatus_FinalizeServiceSession,
|
||||
OperationStatus_InitializeActionCenter,
|
||||
OperationStatus_InitializeBrowser,
|
||||
OperationStatus_InitializeClient,
|
||||
OperationStatus_InitializeConfiguration,
|
||||
|
@ -64,7 +63,7 @@ namespace SafeExamBrowser.Contracts.I18n
|
|||
OperationStatus_InitializeProcessMonitoring,
|
||||
OperationStatus_InitializeRuntimeConnection,
|
||||
OperationStatus_InitializeServiceSession,
|
||||
OperationStatus_InitializeTaskbar,
|
||||
OperationStatus_InitializeShell,
|
||||
OperationStatus_InitializeWindowMonitoring,
|
||||
OperationStatus_InitializeWorkingArea,
|
||||
OperationStatus_RestartCommunicationHost,
|
||||
|
@ -81,9 +80,8 @@ namespace SafeExamBrowser.Contracts.I18n
|
|||
OperationStatus_StopMouseInterception,
|
||||
OperationStatus_StopProcessMonitoring,
|
||||
OperationStatus_StopWindowMonitoring,
|
||||
OperationStatus_TerminateActionCenter,
|
||||
OperationStatus_TerminateBrowser,
|
||||
OperationStatus_TerminateTaskbar,
|
||||
OperationStatus_TerminateShell,
|
||||
OperationStatus_WaitExplorerStartup,
|
||||
OperationStatus_WaitExplorerTermination,
|
||||
OperationStatus_WaitRuntimeDisconnection,
|
||||
|
|
|
@ -17,9 +17,14 @@ namespace SafeExamBrowser.Contracts.SystemComponents
|
|||
public interface ISystemComponent<TControl> where TControl : ISystemControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the resources and operations of the component and registers its taskbar control.
|
||||
/// Initializes the resources and operations of the component.
|
||||
/// </summary>
|
||||
void Initialize(TControl control);
|
||||
void Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Registers a system control which will be loaded into shell.
|
||||
/// </summary>
|
||||
void Register(TControl control);
|
||||
|
||||
/// <summary>
|
||||
/// 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);
|
||||
|
||||
/// <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>
|
||||
INotificationControl CreateNotificationControl(INotificationInfo info);
|
||||
INotificationControl CreateNotificationControl(INotificationInfo info, Location location);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a password dialog with the given message and title.
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
namespace SafeExamBrowser.Contracts.UserInterface.Shell
|
||||
{
|
||||
/// <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>
|
||||
public interface ISystemControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Closes any pop-up windows associated with this control.
|
||||
/// Closes the control and / or any associated user interface elements.
|
||||
/// </summary>
|
||||
void Close();
|
||||
|
||||
|
|
|
@ -126,9 +126,6 @@
|
|||
<Entry key="OperationStatus_FinalizeServiceSession">
|
||||
Finalizing service session
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_InitializeActionCenter">
|
||||
Initializing action center
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_InitializeBrowser">
|
||||
Initializing browser
|
||||
</Entry>
|
||||
|
@ -153,8 +150,8 @@
|
|||
<Entry key="OperationStatus_InitializeSession">
|
||||
Initializing new session
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_InitializeTaskbar">
|
||||
Initializing taskbar
|
||||
<Entry key="OperationStatus_InitializeShell">
|
||||
Initializing user interface
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_InitializeWindowMonitoring">
|
||||
Initializing window monitoring
|
||||
|
@ -201,14 +198,11 @@
|
|||
<Entry key="OperationStatus_StopWindowMonitoring">
|
||||
Stopping window monitoring
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_TerminateActionCenter">
|
||||
Terminating action center
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_TerminateBrowser">
|
||||
Terminating browser
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_TerminateTaskbar">
|
||||
Terminating taskbar
|
||||
<Entry key="OperationStatus_TerminateShell">
|
||||
Terminating user interface
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_WaitExplorerStartup">
|
||||
Waiting for Windows explorer to start up
|
||||
|
|
|
@ -21,23 +21,19 @@ namespace SafeExamBrowser.SystemComponents
|
|||
private IList<KeyboardLayoutDefinition> layouts = new List<KeyboardLayoutDefinition>();
|
||||
private ILogger logger;
|
||||
private InputLanguage originalLanguage;
|
||||
private ISystemKeyboardLayoutControl control;
|
||||
private IList<ISystemKeyboardLayoutControl> controls;
|
||||
private IText text;
|
||||
|
||||
public KeyboardLayout(ILogger logger, IText text)
|
||||
{
|
||||
this.controls = new List<ISystemKeyboardLayoutControl>();
|
||||
this.logger = logger;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void Initialize(ISystemKeyboardLayoutControl control)
|
||||
public void Initialize()
|
||||
{
|
||||
this.control = control;
|
||||
|
||||
originalLanguage = InputLanguage.CurrentInputLanguage;
|
||||
control.LayoutSelected += Control_LayoutSelected;
|
||||
control.SetTooltip(text.Get(TextKey.SystemControl_KeyboardLayoutTooltip));
|
||||
|
||||
logger.Info($"Saved current keyboard layout {ToString(originalLanguage)}.");
|
||||
|
||||
foreach (InputLanguage language in InputLanguage.InstalledInputLanguages)
|
||||
|
@ -50,22 +46,36 @@ namespace SafeExamBrowser.SystemComponents
|
|||
Name = language.LayoutName
|
||||
};
|
||||
|
||||
control.Add(layout);
|
||||
layouts.Add(layout);
|
||||
|
||||
logger.Info($"Added keyboard layout {ToString(language)} to system control.");
|
||||
logger.Info($"Detected keyboard layout {ToString(language)}.");
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
control?.Close();
|
||||
|
||||
if (originalLanguage != null)
|
||||
{
|
||||
InputLanguage.CurrentInputLanguage = originalLanguage;
|
||||
logger.Info($"Restored original keyboard layout {ToString(originalLanguage)}.");
|
||||
}
|
||||
|
||||
foreach (var control in controls)
|
||||
{
|
||||
control.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void Control_LayoutSelected(IKeyboardLayout layout)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Timers;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
|
@ -23,22 +24,19 @@ namespace SafeExamBrowser.SystemComponents
|
|||
|
||||
private bool infoShown, warningShown;
|
||||
private ILogger logger;
|
||||
private ISystemPowerSupplyControl control;
|
||||
private IList<ISystemPowerSupplyControl> controls;
|
||||
private IText text;
|
||||
private Timer timer;
|
||||
|
||||
public PowerSupply(ILogger logger, IText text)
|
||||
{
|
||||
this.controls = new List<ISystemPowerSupplyControl>();
|
||||
this.logger = logger;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void Initialize(ISystemPowerSupplyControl control)
|
||||
public void Initialize()
|
||||
{
|
||||
this.control = control;
|
||||
|
||||
UpdateControl();
|
||||
|
||||
timer = new Timer(TWO_SECONDS);
|
||||
timer.Elapsed += Timer_Elapsed;
|
||||
timer.AutoReset = true;
|
||||
|
@ -47,19 +45,32 @@ namespace SafeExamBrowser.SystemComponents
|
|||
logger.Info("Started monitoring the power supply.");
|
||||
}
|
||||
|
||||
public void Register(ISystemPowerSupplyControl control)
|
||||
{
|
||||
controls.Add(control);
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
{
|
||||
timer?.Stop();
|
||||
control?.Close();
|
||||
logger.Info("Stopped monitoring the power supply.");
|
||||
if (timer != null)
|
||||
{
|
||||
timer.Stop();
|
||||
logger.Info("Stopped monitoring the power supply.");
|
||||
}
|
||||
|
||||
foreach (var control in controls)
|
||||
{
|
||||
control.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
UpdateControl();
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void UpdateControl()
|
||||
private void UpdateControls()
|
||||
{
|
||||
var charge = SystemInformation.PowerStatus.BatteryLifePercent;
|
||||
var percentage = Math.Round(charge * 100);
|
||||
|
@ -67,32 +78,35 @@ namespace SafeExamBrowser.SystemComponents
|
|||
var online = SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online;
|
||||
var tooltip = string.Empty;
|
||||
|
||||
if (online)
|
||||
foreach (var control in controls)
|
||||
{
|
||||
tooltip = text.Get(percentage == 100 ? TextKey.SystemControl_BatteryCharged : TextKey.SystemControl_BatteryCharging);
|
||||
infoShown = false;
|
||||
warningShown = false;
|
||||
if (online)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -25,38 +25,30 @@ namespace SafeExamBrowser.SystemComponents
|
|||
private const int TWO_SECONDS = 2000;
|
||||
private readonly object @lock = new object();
|
||||
|
||||
private ISystemWirelessNetworkControl control;
|
||||
private IList<ISystemWirelessNetworkControl> controls;
|
||||
private IList<WirelessNetworkDefinition> networks;
|
||||
private bool hasWifiAdapter;
|
||||
private ILogger logger;
|
||||
private IList<WirelessNetworkDefinition> networks = new List<WirelessNetworkDefinition>();
|
||||
private IText text;
|
||||
private Timer timer;
|
||||
private Wifi wifi;
|
||||
|
||||
public WirelessNetwork(ILogger logger, IText text)
|
||||
{
|
||||
this.controls = new List<ISystemWirelessNetworkControl>();
|
||||
this.logger = logger;
|
||||
this.networks = new List<WirelessNetworkDefinition>();
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void Initialize(ISystemWirelessNetworkControl control)
|
||||
public void Initialize()
|
||||
{
|
||||
this.control = control;
|
||||
this.wifi = new Wifi();
|
||||
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.Elapsed += Timer_Elapsed;
|
||||
timer.AutoReset = true;
|
||||
|
@ -64,17 +56,45 @@ namespace SafeExamBrowser.SystemComponents
|
|||
|
||||
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()
|
||||
{
|
||||
timer?.Stop();
|
||||
control?.Close();
|
||||
|
||||
if (timer != null)
|
||||
{
|
||||
timer.Stop();
|
||||
logger.Info("Stopped monitoring the wireless network adapter.");
|
||||
}
|
||||
|
||||
foreach (var control in controls)
|
||||
{
|
||||
control.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void Control_NetworkSelected(IWirelessNetwork network)
|
||||
|
@ -85,7 +105,11 @@ namespace SafeExamBrowser.SystemComponents
|
|||
var authRequest = new AuthRequest(accessPoint);
|
||||
|
||||
accessPoint.ConnectAsync(authRequest, false, (success) => AccessPoint_OnConnectComplete(network.Name, success));
|
||||
control.IsConnecting = true;
|
||||
|
||||
foreach (var control in controls)
|
||||
{
|
||||
control.IsConnecting = true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -104,18 +128,22 @@ namespace SafeExamBrowser.SystemComponents
|
|||
logger.Error($"Failed to connect to wireless network '{name}!'");
|
||||
}
|
||||
|
||||
control.IsConnecting = false;
|
||||
UpdateControl();
|
||||
foreach (var control in controls)
|
||||
{
|
||||
control.IsConnecting = false;
|
||||
}
|
||||
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
UpdateControl();
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void Wifi_ConnectionStatusChanged(object sender, WifiStatusEventArgs e)
|
||||
{
|
||||
UpdateControl();
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private bool IsTurnedOff()
|
||||
|
@ -143,12 +171,15 @@ namespace SafeExamBrowser.SystemComponents
|
|||
return true;
|
||||
}
|
||||
|
||||
private void UpdateControl()
|
||||
private void UpdateControls()
|
||||
{
|
||||
lock (@lock)
|
||||
{
|
||||
try
|
||||
{
|
||||
var isConnected = false;
|
||||
var networkName = string.Empty;
|
||||
|
||||
networks.Clear();
|
||||
|
||||
foreach (var accessPoint in wifi.GetAccessPoints())
|
||||
|
@ -156,22 +187,28 @@ namespace SafeExamBrowser.SystemComponents
|
|||
// The user may only connect to an already configured wireless network!
|
||||
if (accessPoint.HasProfile)
|
||||
{
|
||||
networks.Add(ToDefinition(accessPoint));
|
||||
networkName = accessPoint.Name;
|
||||
isConnected = accessPoint.IsConnected;
|
||||
|
||||
if (accessPoint.IsConnected)
|
||||
{
|
||||
control.SetTooltip(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", accessPoint.Name));
|
||||
}
|
||||
networks.Add(ToDefinition(accessPoint));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
control.Update(new List<IWirelessNetwork>(networks));
|
||||
if (isConnected)
|
||||
{
|
||||
control.SetTooltip(text.Get(TextKey.SystemControl_WirelessConnected).Replace("%%NAME%%", networkName));
|
||||
}
|
||||
|
||||
control.NetworkStatus = ToStatus(wifi.ConnectionStatus);
|
||||
control.Update(new List<IWirelessNetwork>(networks));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -20,14 +20,6 @@
|
|||
<ScrollViewer Grid.Row="0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
|
||||
<StackPanel x:Name="ApplicationPanel" Orientation="Vertical" />
|
||||
</ScrollViewer>
|
||||
<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>
|
||||
<UniformGrid x:Name="ControlPanel" Grid.Row="1" Columns="4" Margin="5" />
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
|
@ -33,12 +33,18 @@ namespace SafeExamBrowser.UserInterface.Desktop
|
|||
|
||||
public void AddNotificationControl(INotificationControl control)
|
||||
{
|
||||
|
||||
if (control is UIElement uiElement)
|
||||
{
|
||||
ControlPanel.Children.Add(uiElement);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSystemControl(ISystemControl control)
|
||||
{
|
||||
|
||||
if (control is UIElement uiElement)
|
||||
{
|
||||
ControlPanel.Children.Add(uiElement);
|
||||
}
|
||||
}
|
||||
|
||||
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:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
@ -15,11 +15,11 @@ using SafeExamBrowser.UserInterface.Desktop.Utilities;
|
|||
|
||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
|
||||
{
|
||||
public partial class NotificationButton : UserControl, INotificationControl
|
||||
public partial class TaskbarNotificationButton : UserControl, INotificationControl
|
||||
{
|
||||
public event NotificationControlClickedEventHandler Clicked;
|
||||
|
||||
public NotificationButton(INotificationInfo info)
|
||||
public TaskbarNotificationButton(INotificationInfo info)
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeNotificationIcon(info);
|
|
@ -80,6 +80,9 @@
|
|||
<Compile Include="Controls\ActionCenterApplicationButton.xaml.cs">
|
||||
<DependentUpon>ActionCenterApplicationButton.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\ActionCenterNotificationButton.xaml.cs">
|
||||
<DependentUpon>ActionCenterNotificationButton.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\TaskbarApplicationControl.xaml.cs">
|
||||
<DependentUpon>TaskbarApplicationControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -95,8 +98,8 @@
|
|||
<Compile Include="Controls\KeyboardLayoutControl.xaml.cs">
|
||||
<DependentUpon>KeyboardLayoutControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\NotificationButton.xaml.cs">
|
||||
<DependentUpon>NotificationButton.xaml</DependentUpon>
|
||||
<Compile Include="Controls\TaskbarNotificationButton.xaml.cs">
|
||||
<DependentUpon>TaskbarNotificationButton.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\PowerSupplyControl.xaml.cs">
|
||||
<DependentUpon>PowerSupplyControl.xaml</DependentUpon>
|
||||
|
@ -151,6 +154,10 @@
|
|||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\ActionCenterNotificationButton.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\TaskbarApplicationControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -171,7 +178,7 @@
|
|||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\NotificationButton.xaml">
|
||||
<Page Include="Controls\TaskbarNotificationButton.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
|
|
|
@ -86,9 +86,16 @@ namespace SafeExamBrowser.UserInterface.Desktop
|
|||
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)
|
||||
|
|
Loading…
Reference in a new issue