Started implementing system controls. Introduced sytem information module...

This commit is contained in:
Damian Büchel 2017-08-14 17:44:16 +02:00
parent b80863c7aa
commit a5d44e1ef8
12 changed files with 273 additions and 16 deletions

View file

@ -50,7 +50,6 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
@ -65,6 +64,7 @@
<Compile Include="MouseSettings.cs" />
<Compile Include="Settings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SystemInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj">

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2017 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.Forms;
using SafeExamBrowser.Contracts.Configuration;
namespace SafeExamBrowser.Configuration
{
public class SystemInfo : ISystemInfo
{
public bool HasBattery { get; private set; }
public OperatingSystem OperatingSystem { get; private set; }
public string OperatingSystemInfo
{
get { return $"{OperatingSystemName()}, {System.Environment.OSVersion.VersionString} ({Architecture()})"; }
}
public SystemInfo()
{
InitializeBattery();
InitializeOperatingSystem();
}
private void InitializeBattery()
{
var status = SystemInformation.PowerStatus.BatteryChargeStatus;
HasBattery = !status.HasFlag(BatteryChargeStatus.NoSystemBattery) && !status.HasFlag(BatteryChargeStatus.Unknown);
}
private void InitializeOperatingSystem()
{
// See https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions for mapping source...
var major = System.Environment.OSVersion.Version.Major;
var minor = System.Environment.OSVersion.Version.Minor;
if (major == 6)
{
if (minor == 1)
{
OperatingSystem = OperatingSystem.Windows7;
}
else if (minor == 2)
{
OperatingSystem = OperatingSystem.Windows8;
}
else if (minor == 3)
{
OperatingSystem = OperatingSystem.Windows8_1;
}
}
else if (major == 10)
{
OperatingSystem = OperatingSystem.Windows10;
}
}
private string OperatingSystemName()
{
switch (OperatingSystem)
{
case OperatingSystem.Windows7:
return "Windows 7";
case OperatingSystem.Windows8:
return "Windows 8";
case OperatingSystem.Windows8_1:
return "Windows 8.1";
case OperatingSystem.Windows10:
return "Windows 10";
default:
return "Unknown Windows Version";
}
}
private string Architecture()
{
return System.Environment.Is64BitOperatingSystem ? "x64" : "x86";
}
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Contracts.Configuration
{
public interface ISystemInfo
{
/// <summary>
/// Reveals whether the computer system contains a battery.
/// </summary>
bool HasBattery { get; }
/// <summary>
/// Reveals the version of the currently running operating system.
/// </summary>
OperatingSystem OperatingSystem { get; }
/// <summary>
/// Provides detailed version information about the currently running operating system.
/// </summary>
string OperatingSystemInfo { get; }
}
}

View file

@ -0,0 +1,19 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Contracts.Configuration
{
public enum OperatingSystem
{
Unknown = 0,
Windows7,
Windows8,
Windows8_1,
Windows10
}
}

View file

@ -66,6 +66,8 @@
<Compile Include="Configuration\IApplicationInfo.cs" />
<Compile Include="Configuration\IApplicationInstance.cs" />
<Compile Include="Configuration\INotificationInfo.cs" />
<Compile Include="Configuration\ISystemInfo.cs" />
<Compile Include="Configuration\OperatingSystem.cs" />
<Compile Include="Configuration\Settings\IBrowserSettings.cs" />
<Compile Include="Configuration\Settings\IKeyboardSettings.cs" />
<Compile Include="Configuration\Settings\IMouseSettings.cs" />

View file

@ -11,6 +11,7 @@ using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Behaviour;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
@ -24,6 +25,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
{
private Mock<ILogger> loggerMock;
private Mock<ISettings> settingsMock;
private Mock<ISystemInfo> systemInfoMock;
private Mock<IText> textMock;
private Mock<IUserInterfaceFactory> uiFactoryMock;
@ -34,12 +36,13 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
{
loggerMock = new Mock<ILogger>();
settingsMock = new Mock<ISettings>();
systemInfoMock = new Mock<ISystemInfo>();
textMock = new Mock<IText>();
uiFactoryMock = new Mock<IUserInterfaceFactory>();
uiFactoryMock.Setup(f => f.CreateSplashScreen(settingsMock.Object, textMock.Object)).Returns(new Mock<ISplashScreen>().Object);
sut = new StartupController(loggerMock.Object, settingsMock.Object, textMock.Object, uiFactoryMock.Object);
sut = new StartupController(loggerMock.Object, settingsMock.Object, systemInfoMock.Object, textMock.Object, uiFactoryMock.Object);
}
[TestMethod]

View file

@ -7,6 +7,7 @@
*/
using SafeExamBrowser.Contracts.Behaviour;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
@ -19,22 +20,25 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
{
private ILogger logger;
private INotificationController aboutController, logController;
private ISettings settings;
private ISystemInfo systemInfo;
private ITaskbar taskbar;
private IUserInterfaceFactory uiFactory;
private IText text;
private ISettings settings;
public ISplashScreen SplashScreen { private get; set; }
public TaskbarOperation(
ILogger logger,
ISettings settings,
ISystemInfo systemInfo,
ITaskbar taskbar,
IText text,
IUserInterfaceFactory uiFactory)
{
this.logger = logger;
this.settings = settings;
this.systemInfo = systemInfo;
this.taskbar = taskbar;
this.text = text;
this.uiFactory = uiFactory;
@ -51,12 +55,32 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
}
CreateAboutNotification();
if (systemInfo.HasBattery)
{
CreateBatteryNotification();
}
CreateNetworkNotification();
CreateAudioNotification();
CreateKeyboardNotification();
}
public void Revert()
{
logController?.Terminate();
aboutController.Terminate();
aboutController?.Terminate();
}
private void CreateLogNotification()
{
var logInfo = new LogNotificationInfo(text);
var logNotification = uiFactory.CreateNotification(logInfo);
logController = new LogNotificationController(logger, text, uiFactory);
logController.RegisterNotification(logNotification);
taskbar.AddNotification(logNotification);
}
private void CreateAboutNotification()
@ -70,15 +94,25 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
taskbar.AddNotification(aboutNotification);
}
private void CreateLogNotification()
private void CreateBatteryNotification()
{
var logInfo = new LogNotificationInfo(text);
var logNotification = uiFactory.CreateNotification(logInfo);
// TODO: Are these specializations of INotification -> ISystemNotification? If yes, is this the right place, or do they
// need to go to a separate assembly?
}
logController = new LogNotificationController(logger, text, uiFactory);
logController.RegisterNotification(logNotification);
private void CreateNetworkNotification()
{
// TODO
}
taskbar.AddNotification(logNotification);
private void CreateAudioNotification()
{
// TODO
}
private void CreateKeyboardNotification()
{
// TODO
}
}
}

View file

@ -10,6 +10,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using SafeExamBrowser.Contracts.Behaviour;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
@ -22,15 +23,17 @@ namespace SafeExamBrowser.Core.Behaviour
private ILogger logger;
private ISettings settings;
private ISplashScreen splashScreen;
private ISystemInfo systemInfo;
private IText text;
private IUserInterfaceFactory uiFactory;
private Stack<IOperation> stack = new Stack<IOperation>();
public StartupController(ILogger logger, ISettings settings, IText text, IUserInterfaceFactory uiFactory)
public StartupController(ILogger logger, ISettings settings, ISystemInfo systemInfo, IText text, IUserInterfaceFactory uiFactory)
{
this.logger = logger;
this.settings = settings;
this.systemInfo = systemInfo;
this.text = text;
this.uiFactory = uiFactory;
}
@ -87,7 +90,8 @@ namespace SafeExamBrowser.Core.Behaviour
var githubLine = $"/* Please visit https://github.com/SafeExamBrowser for more information.";
logger.Log($"{titleLine}{copyrightLine}{emptyLine}{githubLine}");
logger.Log($"{Environment.NewLine}# Application started at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}{Environment.NewLine}");
logger.Log($"{Environment.NewLine}# Application started at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
logger.Log($"# Operating system: {systemInfo.OperatingSystemInfo}{Environment.NewLine}");
logger.Info("--- Initiating startup procedure ---");
splashScreen = uiFactory.CreateSplashScreen(settings, text);

View file

@ -4,8 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Controls"
mc:Ignorable="d"
d:DesignHeight="16" d:DesignWidth="16" Margin="5,0">
mc:Ignorable="d" d:DesignHeight="16" d:DesignWidth="16" Margin="5,0">
<Grid>
<Button x:Name="IconButton" Click="Icon_Click" Background="#00000000" BorderThickness="0">
<Button.Template>

View file

@ -44,6 +44,7 @@ namespace SafeExamBrowser
private IProcessMonitor processMonitor;
private IRuntimeController runtimeController;
private ISettings settings;
private ISystemInfo systemInfo;
private IText text;
private ITextResource textResource;
private IUserInterfaceFactory uiFactory;
@ -61,6 +62,7 @@ namespace SafeExamBrowser
logFormatter = new DefaultLogFormatter();
nativeMethods = new NativeMethods();
settings = new Settings();
systemInfo = new SystemInfo();
textResource = new XmlTextResource();
uiFactory = new UserInterfaceFactory();
@ -77,14 +79,14 @@ namespace SafeExamBrowser
runtimeController = new RuntimeController(displayMonitor, new ModuleLogger(logger, typeof(RuntimeController)), processMonitor, Taskbar, windowMonitor);
ShutdownController = new ShutdownController(logger, settings, text, uiFactory);
StartupController = new StartupController(logger, settings, text, uiFactory);
StartupController = new StartupController(logger, settings, systemInfo, text, uiFactory);
StartupOperations = new Queue<IOperation>();
StartupOperations.Enqueue(new KeyboardInterceptorOperation(keyboardInterceptor, logger, nativeMethods));
StartupOperations.Enqueue(new WindowMonitorOperation(logger, windowMonitor));
StartupOperations.Enqueue(new ProcessMonitorOperation(logger, processMonitor));
StartupOperations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, Taskbar));
StartupOperations.Enqueue(new TaskbarOperation(logger, settings, Taskbar, text, uiFactory));
StartupOperations.Enqueue(new TaskbarOperation(logger, settings, systemInfo, Taskbar, text, uiFactory));
StartupOperations.Enqueue(new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory));
StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, logger));
StartupOperations.Enqueue(new ClipboardOperation(logger, nativeMethods));

View file

@ -74,6 +74,9 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
@ -110,6 +113,7 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="app.manifest" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel element will disable file and registry virtualization.
Remove this element if your application requires this virtualization for backwards
compatibility.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on and is
is designed to work with. Uncomment the appropriate elements and Windows will
automatically selected the most compatible environment. -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
<!--
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
-->
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>