Implemented basic battery system control.
This commit is contained in:
		
							parent
							
								
									7baf826e5a
								
							
						
					
					
						commit
						0184eb0fe1
					
				
					 18 changed files with 272 additions and 80 deletions
				
			
		| 
						 | 
					@ -43,6 +43,11 @@ namespace SafeExamBrowser.Contracts.I18n
 | 
				
			||||||
		SplashScreen_TerminateBrowser,
 | 
							SplashScreen_TerminateBrowser,
 | 
				
			||||||
		SplashScreen_WaitExplorerStartup,
 | 
							SplashScreen_WaitExplorerStartup,
 | 
				
			||||||
		SplashScreen_WaitExplorerTermination,
 | 
							SplashScreen_WaitExplorerTermination,
 | 
				
			||||||
 | 
							SystemControl_BatteryCharged,
 | 
				
			||||||
 | 
							SystemControl_BatteryCharging,
 | 
				
			||||||
 | 
							SystemControl_BatteryChargeCriticalWarning,
 | 
				
			||||||
 | 
							SystemControl_BatteryChargeLowInfo,
 | 
				
			||||||
 | 
							SystemControl_BatteryRemainingCharge,
 | 
				
			||||||
		Version
 | 
							Version
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,6 +86,7 @@
 | 
				
			||||||
    <Compile Include="Monitoring\KeyModifier.cs" />
 | 
					    <Compile Include="Monitoring\KeyModifier.cs" />
 | 
				
			||||||
    <Compile Include="Monitoring\KeyState.cs" />
 | 
					    <Compile Include="Monitoring\KeyState.cs" />
 | 
				
			||||||
    <Compile Include="Monitoring\MouseButton.cs" />
 | 
					    <Compile Include="Monitoring\MouseButton.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="SystemComponents\BatteryChargeStatus.cs" />
 | 
				
			||||||
    <Compile Include="SystemComponents\ISystemComponent.cs" />
 | 
					    <Compile Include="SystemComponents\ISystemComponent.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\IBrowserControl.cs" />
 | 
					    <Compile Include="UserInterface\IBrowserControl.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\IBrowserWindow.cs" />
 | 
					    <Compile Include="UserInterface\IBrowserWindow.cs" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.SystemComponents
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public enum BatteryChargeStatus
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Undefined = 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The battery charge is critical, i.e. below 20%.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							Critical,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The battery charge is low, i.e. below 35%.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							Low,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The battery charge is okay, i.e. above 35%.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							Okay
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -13,17 +13,12 @@ namespace SafeExamBrowser.Contracts.SystemComponents
 | 
				
			||||||
	public interface ISystemComponent<TControl> where TControl : ISystemControl
 | 
						public interface ISystemComponent<TControl> where TControl : ISystemControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Initializes the resources used by the component and starts its operations, if applicable.
 | 
							/// Initializes the resources and operations of the component and registers its taskbar control.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void Initialize();
 | 
							void Initialize(TControl control);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Registers the taskbar control for the system component.
 | 
							/// Instructs the component to stop any running operations and releases all used resources.
 | 
				
			||||||
		/// </summary>
 | 
					 | 
				
			||||||
		void RegisterControl(TControl control);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/// <summary>
 | 
					 | 
				
			||||||
		/// Instructs the component to stop any running operations and release all used resources.
 | 
					 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void Terminate();
 | 
							void Terminate();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,11 @@ namespace SafeExamBrowser.Contracts.UserInterface.Taskbar
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public interface ISystemControl
 | 
						public interface ISystemControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Closes any pop-up windows associated with this control.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							void Close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Sets the tooltip text of the system control.
 | 
							/// Sets the tooltip text of the system control.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,19 +6,30 @@
 | 
				
			||||||
 * 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 SafeExamBrowser.Contracts.SystemComponents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Contracts.UserInterface.Taskbar
 | 
					namespace SafeExamBrowser.Contracts.UserInterface.Taskbar
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public interface ISystemPowerSupplyControl : ISystemControl
 | 
						public interface ISystemPowerSupplyControl : ISystemControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Sets the current charge of the system battery, if available. <c>0.0</c> means the battery is empty, <c>1.0</c> means it's
 | 
							/// Sets the current charge of the system battery: <c>0.0</c> means the battery is empty, <c>1.0</c> means it's fully charged.
 | 
				
			||||||
		/// fully charged. Pass <c>null</c> to indicate that the computer system has no battery.
 | 
					 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void SetBatteryCharge(double? percentage);
 | 
							void SetBatteryCharge(double charge, BatteryChargeStatus status);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Sets the power supply status, i.e. whether the computer system is connected to the power grid or not.
 | 
							/// Sets the power supply status, i.e. whether the computer system is connected to the power grid or not.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void SetPowerGridConnection(bool connected);
 | 
							void SetPowerGridConnection(bool connected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Warns the user that the battery charge is critical.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							void ShowCriticalBatteryWarning(string warning);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Indicates the user that the battery charge is low.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							void ShowLowBatteryInfo(string info);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,7 +60,11 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			CreateAboutNotification();
 | 
								CreateAboutNotification();
 | 
				
			||||||
			CreatePowerSupplyComponent();
 | 
					
 | 
				
			||||||
 | 
								if (systemInfo.HasBattery)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									CreatePowerSupplyComponent();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void Revert()
 | 
							public void Revert()
 | 
				
			||||||
| 
						 | 
					@ -68,7 +72,10 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
			logController?.Terminate();
 | 
								logController?.Terminate();
 | 
				
			||||||
			aboutController?.Terminate();
 | 
								aboutController?.Terminate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			powerSupply.Terminate();
 | 
								if (systemInfo.HasBattery)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									powerSupply.Terminate();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void CreateLogNotification()
 | 
							private void CreateLogNotification()
 | 
				
			||||||
| 
						 | 
					@ -97,9 +104,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var control = uiFactory.CreatePowerSupplyControl();
 | 
								var control = uiFactory.CreatePowerSupplyControl();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			powerSupply.RegisterControl(control);
 | 
								powerSupply.Initialize(control);
 | 
				
			||||||
			powerSupply.Initialize();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			taskbar.AddSystemControl(control);
 | 
								taskbar.AddSystemControl(control);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,32 +1,37 @@
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8" ?>
 | 
					<?xml version="1.0" encoding="utf-8" ?>
 | 
				
			||||||
<Text>
 | 
					<Text>
 | 
				
			||||||
  <Browser_ShowDeveloperConsole>Open Console</Browser_ShowDeveloperConsole>
 | 
						<Browser_ShowDeveloperConsole>Open Console</Browser_ShowDeveloperConsole>
 | 
				
			||||||
  <LogWindow_Title>Application Log</LogWindow_Title>
 | 
						<LogWindow_Title>Application Log</LogWindow_Title>
 | 
				
			||||||
  <MessageBox_ShutdownError>An unexpected error occurred during the shutdown procedure! Please consult the application log for more information...</MessageBox_ShutdownError>
 | 
						<MessageBox_ShutdownError>An unexpected error occurred during the shutdown procedure! Please consult the application log for more information...</MessageBox_ShutdownError>
 | 
				
			||||||
  <MessageBox_ShutdownErrorTitle>Shutdown Error</MessageBox_ShutdownErrorTitle>
 | 
						<MessageBox_ShutdownErrorTitle>Shutdown Error</MessageBox_ShutdownErrorTitle>
 | 
				
			||||||
  <MessageBox_StartupError>An unexpected error occurred during the startup procedure! Please consult the application log for more information...</MessageBox_StartupError>
 | 
						<MessageBox_StartupError>An unexpected error occurred during the startup procedure! Please consult the application log for more information...</MessageBox_StartupError>
 | 
				
			||||||
  <MessageBox_StartupErrorTitle>Startup Error</MessageBox_StartupErrorTitle>
 | 
						<MessageBox_StartupErrorTitle>Startup Error</MessageBox_StartupErrorTitle>
 | 
				
			||||||
  <Notification_AboutTooltip>About Safe Exam Browser</Notification_AboutTooltip>
 | 
						<Notification_AboutTooltip>About Safe Exam Browser</Notification_AboutTooltip>
 | 
				
			||||||
  <Notification_LogTooltip>Application Log</Notification_LogTooltip>
 | 
						<Notification_LogTooltip>Application Log</Notification_LogTooltip>
 | 
				
			||||||
  <SplashScreen_EmptyClipboard>Emptying clipboard</SplashScreen_EmptyClipboard>
 | 
						<SplashScreen_EmptyClipboard>Emptying clipboard</SplashScreen_EmptyClipboard>
 | 
				
			||||||
  <SplashScreen_InitializeBrowser>Initializing browser</SplashScreen_InitializeBrowser>
 | 
						<SplashScreen_InitializeBrowser>Initializing browser</SplashScreen_InitializeBrowser>
 | 
				
			||||||
  <SplashScreen_InitializeProcessMonitoring>Initializing process monitoring</SplashScreen_InitializeProcessMonitoring>
 | 
						<SplashScreen_InitializeProcessMonitoring>Initializing process monitoring</SplashScreen_InitializeProcessMonitoring>
 | 
				
			||||||
  <SplashScreen_InitializeTaskbar>Initializing taskbar</SplashScreen_InitializeTaskbar>
 | 
						<SplashScreen_InitializeTaskbar>Initializing taskbar</SplashScreen_InitializeTaskbar>
 | 
				
			||||||
  <SplashScreen_InitializeWindowMonitoring>Initializing window monitoring</SplashScreen_InitializeWindowMonitoring>
 | 
						<SplashScreen_InitializeWindowMonitoring>Initializing window monitoring</SplashScreen_InitializeWindowMonitoring>
 | 
				
			||||||
  <SplashScreen_InitializeWorkingArea>Initializing working area</SplashScreen_InitializeWorkingArea>
 | 
						<SplashScreen_InitializeWorkingArea>Initializing working area</SplashScreen_InitializeWorkingArea>
 | 
				
			||||||
  <SplashScreen_RestoreWorkingArea>Restoring working area</SplashScreen_RestoreWorkingArea>
 | 
						<SplashScreen_RestoreWorkingArea>Restoring working area</SplashScreen_RestoreWorkingArea>
 | 
				
			||||||
  <SplashScreen_ShutdownProcedure>Initiating shutdown procedure</SplashScreen_ShutdownProcedure>
 | 
						<SplashScreen_ShutdownProcedure>Initiating shutdown procedure</SplashScreen_ShutdownProcedure>
 | 
				
			||||||
  <SplashScreen_StartEventHandling>Starting event handling</SplashScreen_StartEventHandling>
 | 
						<SplashScreen_StartEventHandling>Starting event handling</SplashScreen_StartEventHandling>
 | 
				
			||||||
  <SplashScreen_StartKeyboardInterception>Starting keyboard interception</SplashScreen_StartKeyboardInterception>
 | 
						<SplashScreen_StartKeyboardInterception>Starting keyboard interception</SplashScreen_StartKeyboardInterception>
 | 
				
			||||||
  <SplashScreen_StartMouseInterception>Starting mouse interception</SplashScreen_StartMouseInterception>
 | 
						<SplashScreen_StartMouseInterception>Starting mouse interception</SplashScreen_StartMouseInterception>
 | 
				
			||||||
  <SplashScreen_StartupProcedure>Initiating startup procedure</SplashScreen_StartupProcedure>
 | 
						<SplashScreen_StartupProcedure>Initiating startup procedure</SplashScreen_StartupProcedure>
 | 
				
			||||||
  <SplashScreen_StopEventHandling>Stopping event handling</SplashScreen_StopEventHandling>
 | 
						<SplashScreen_StopEventHandling>Stopping event handling</SplashScreen_StopEventHandling>
 | 
				
			||||||
  <SplashScreen_StopKeyboardInterception>Stopping keyboard interception</SplashScreen_StopKeyboardInterception>
 | 
						<SplashScreen_StopKeyboardInterception>Stopping keyboard interception</SplashScreen_StopKeyboardInterception>
 | 
				
			||||||
  <SplashScreen_StopMouseInterception>Stopping mouse interception</SplashScreen_StopMouseInterception>
 | 
						<SplashScreen_StopMouseInterception>Stopping mouse interception</SplashScreen_StopMouseInterception>
 | 
				
			||||||
  <SplashScreen_StopProcessMonitoring>Stopping process monitoring</SplashScreen_StopProcessMonitoring>
 | 
						<SplashScreen_StopProcessMonitoring>Stopping process monitoring</SplashScreen_StopProcessMonitoring>
 | 
				
			||||||
  <SplashScreen_StopWindowMonitoring>Stopping window monitoring</SplashScreen_StopWindowMonitoring>
 | 
						<SplashScreen_StopWindowMonitoring>Stopping window monitoring</SplashScreen_StopWindowMonitoring>
 | 
				
			||||||
  <SplashScreen_TerminateBrowser>Terminating browser</SplashScreen_TerminateBrowser>
 | 
						<SplashScreen_TerminateBrowser>Terminating browser</SplashScreen_TerminateBrowser>
 | 
				
			||||||
  <SplashScreen_WaitExplorerStartup>Waiting for Windows explorer to start up</SplashScreen_WaitExplorerStartup>
 | 
						<SplashScreen_WaitExplorerStartup>Waiting for Windows explorer to start up</SplashScreen_WaitExplorerStartup>
 | 
				
			||||||
  <SplashScreen_WaitExplorerTermination>Waiting for Windows explorer to shut down</SplashScreen_WaitExplorerTermination>
 | 
						<SplashScreen_WaitExplorerTermination>Waiting for Windows explorer to shut down</SplashScreen_WaitExplorerTermination>
 | 
				
			||||||
  <Version>Version</Version>
 | 
						<SystemControl_BatteryCharging>Charging... (%%CHARGE%%%)</SystemControl_BatteryCharging>
 | 
				
			||||||
 | 
						<SystemControl_BatteryCharged>Fully charged (%%CHARGE%%%)</SystemControl_BatteryCharged>
 | 
				
			||||||
 | 
						<SystemControl_BatteryChargeCriticalWarning>The battery charge is critically low. Please connect your computer to a power supply!</SystemControl_BatteryChargeCriticalWarning>
 | 
				
			||||||
 | 
						<SystemControl_BatteryChargeLowInfo>The battery charge is getting low. Consider connecting your computer to a power supply in time...</SystemControl_BatteryChargeLowInfo>
 | 
				
			||||||
 | 
						<SystemControl_BatteryRemainingCharge>%%HOURS%%h %%MINUTES%%min remaining (%%CHARGE%%%)</SystemControl_BatteryRemainingCharge>
 | 
				
			||||||
 | 
						<Version>Version</Version>
 | 
				
			||||||
</Text>
 | 
					</Text>
 | 
				
			||||||
| 
						 | 
					@ -6,35 +6,102 @@
 | 
				
			||||||
 * 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;
 | 
				
			||||||
 | 
					using System.Timers;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.I18n;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Logging;
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
using SafeExamBrowser.Contracts.SystemComponents;
 | 
					using SafeExamBrowser.Contracts.SystemComponents;
 | 
				
			||||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
 | 
					using SafeExamBrowser.Contracts.UserInterface.Taskbar;
 | 
				
			||||||
 | 
					using PowerLineStatus = System.Windows.Forms.PowerLineStatus;
 | 
				
			||||||
 | 
					using SystemInformation = System.Windows.Forms.SystemInformation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.SystemComponents
 | 
					namespace SafeExamBrowser.SystemComponents
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public class PowerSupply : ISystemComponent<ISystemPowerSupplyControl>
 | 
						public class PowerSupply : ISystemComponent<ISystemPowerSupplyControl>
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							private const int TWO_SECONDS = 2000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private bool infoShown, warningShown;
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private ISystemPowerSupplyControl control;
 | 
							private ISystemPowerSupplyControl control;
 | 
				
			||||||
 | 
							private IText text;
 | 
				
			||||||
 | 
							private Timer timer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public PowerSupply(ILogger logger)
 | 
							public PowerSupply(ILogger logger, IText text)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.logger = logger;
 | 
								this.logger = logger;
 | 
				
			||||||
 | 
								this.text = text;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void Initialize()
 | 
							public void Initialize(ISystemPowerSupplyControl control)
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		public void RegisterControl(ISystemPowerSupplyControl control)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.control = control;
 | 
								this.control = control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								UpdateControl();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								timer = new Timer(TWO_SECONDS);
 | 
				
			||||||
 | 
								timer.Elapsed += Timer_Elapsed;
 | 
				
			||||||
 | 
								timer.AutoReset = true;
 | 
				
			||||||
 | 
								timer.Start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								logger.Info("Started monitoring the power supply.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Timer_Elapsed(object sender, ElapsedEventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								UpdateControl();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void Terminate()
 | 
							public void Terminate()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								timer?.Stop();
 | 
				
			||||||
 | 
								control?.Close();
 | 
				
			||||||
 | 
								logger.Info("Stopped monitoring the power supply.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void UpdateControl()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var charge = SystemInformation.PowerStatus.BatteryLifePercent;
 | 
				
			||||||
 | 
								var percentage = Math.Round(charge * 100);
 | 
				
			||||||
 | 
								var status = charge <= 0.35 ? (charge <= 0.2 ? BatteryChargeStatus.Critical : BatteryChargeStatus.Low) : BatteryChargeStatus.Okay;
 | 
				
			||||||
 | 
								var online = SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online;
 | 
				
			||||||
 | 
								var tooltip = string.Empty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (status == BatteryChargeStatus.Low && !infoShown)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										control.ShowLowBatteryInfo(text.Get(TextKey.SystemControl_BatteryChargeLowInfo));
 | 
				
			||||||
 | 
										infoShown = true;
 | 
				
			||||||
 | 
										logger.Info("Informed the user about low battery charge.");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (status == BatteryChargeStatus.Critical && !warningShown)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										control.ShowCriticalBatteryWarning(text.Get(TextKey.SystemControl_BatteryChargeCriticalWarning));
 | 
				
			||||||
 | 
										warningShown = true;
 | 
				
			||||||
 | 
										logger.Warn("Warned the user about critical battery charge.");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									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);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,7 @@
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <Reference Include="System" />
 | 
					    <Reference Include="System" />
 | 
				
			||||||
    <Reference Include="Microsoft.CSharp" />
 | 
					    <Reference Include="Microsoft.CSharp" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Windows.Forms" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <Compile Include="PowerSupply.cs" />
 | 
					    <Compile Include="PowerSupply.cs" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@
 | 
				
			||||||
    <UserControl.Resources>
 | 
					    <UserControl.Resources>
 | 
				
			||||||
        <ResourceDictionary>
 | 
					        <ResourceDictionary>
 | 
				
			||||||
            <ResourceDictionary.MergedDictionaries>
 | 
					            <ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
                <ResourceDictionary Source="../Styles/ButtonStyles.xaml"/>
 | 
					                <ResourceDictionary Source="../Templates/Buttons.xaml"/>
 | 
				
			||||||
            </ResourceDictionary.MergedDictionaries>
 | 
					            </ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
        </ResourceDictionary>
 | 
					        </ResourceDictionary>
 | 
				
			||||||
    </UserControl.Resources>
 | 
					    </UserControl.Resources>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@
 | 
				
			||||||
    <UserControl.Resources>
 | 
					    <UserControl.Resources>
 | 
				
			||||||
        <ResourceDictionary>
 | 
					        <ResourceDictionary>
 | 
				
			||||||
            <ResourceDictionary.MergedDictionaries>
 | 
					            <ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
                <ResourceDictionary Source="../Styles/ButtonStyles.xaml"/>
 | 
					                <ResourceDictionary Source="../Templates/Buttons.xaml"/>
 | 
				
			||||||
            </ResourceDictionary.MergedDictionaries>
 | 
					            </ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
        </ResourceDictionary>
 | 
					        </ResourceDictionary>
 | 
				
			||||||
    </UserControl.Resources>
 | 
					    </UserControl.Resources>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,19 +8,46 @@
 | 
				
			||||||
    <UserControl.Resources>
 | 
					    <UserControl.Resources>
 | 
				
			||||||
        <ResourceDictionary>
 | 
					        <ResourceDictionary>
 | 
				
			||||||
            <ResourceDictionary.MergedDictionaries>
 | 
					            <ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
                <ResourceDictionary Source="../Styles/ButtonStyles.xaml"/>
 | 
					                <ResourceDictionary Source="../Templates/Buttons.xaml"/>
 | 
				
			||||||
            </ResourceDictionary.MergedDictionaries>
 | 
					            </ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
        </ResourceDictionary>
 | 
					        </ResourceDictionary>
 | 
				
			||||||
    </UserControl.Resources>
 | 
					    </UserControl.Resources>
 | 
				
			||||||
    <Button x:Name="Button" Background="#00000000" BorderThickness="0" Foreground="White" Padding="5,0"
 | 
					    <Grid>
 | 
				
			||||||
            Template="{StaticResource ResourceKey=TaskbarButton}" Width="28">
 | 
					        <Popup x:Name="Popup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}" AllowsTransparency="True">
 | 
				
			||||||
        <Canvas Height="18" Width="18">
 | 
					            <Border BorderBrush="White" BorderThickness="0.5,0.5,0.5,0" MaxWidth="250" Padding="5">
 | 
				
			||||||
            <Path Stroke="White" Data="M3,6 H17 V9 H18 V11 H17 V9 H17 V14 H3 Z" Panel.ZIndex="2" />
 | 
					                <Border.Background>
 | 
				
			||||||
            <Rectangle x:Name="BatteryCharge" Canvas.Left="3" Canvas.Top="6" Fill="Green" Height="8" Width="14" />
 | 
					                    <SolidColorBrush Color="Black" Opacity="0.8" />
 | 
				
			||||||
            <Grid x:Name="PowerPlug" Panel.ZIndex="3">
 | 
					                </Border.Background>
 | 
				
			||||||
                <Path Stroke="White" Fill="Black" Data="M2.5,14.5 V10 Q5,10 5,6 H4 V4 H4 V6 H1 V4 H1 V6 H0 Q0,10 2.5,10" Panel.ZIndex="2" />
 | 
					                <Grid>
 | 
				
			||||||
                <Path Stroke="Black" Data="M4,14.5 V10 Q6,10 6,5.5" Panel.ZIndex="1" />
 | 
					                    <Grid.RowDefinitions>
 | 
				
			||||||
            </Grid>
 | 
					                        <RowDefinition />
 | 
				
			||||||
        </Canvas>
 | 
					                        <RowDefinition />
 | 
				
			||||||
    </Button>
 | 
					                    </Grid.RowDefinitions>
 | 
				
			||||||
 | 
					                    <Grid Grid.Row="0">
 | 
				
			||||||
 | 
					                        <Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="*" />
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="Auto" />
 | 
				
			||||||
 | 
					                        </Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					                        <Button Grid.Column="1" Background="Transparent" Click="Button_Click" Cursor="Hand" FontWeight="Bold"
 | 
				
			||||||
 | 
					                                Foreground="White" Template="{StaticResource ResourceKey=TaskbarButton}" Width="20">X</Button>
 | 
				
			||||||
 | 
					                    </Grid>
 | 
				
			||||||
 | 
					                    <TextBlock Grid.Row="1" x:Name="PopupText" Foreground="White" TextWrapping="Wrap" />
 | 
				
			||||||
 | 
					                </Grid>
 | 
				
			||||||
 | 
					            </Border>
 | 
				
			||||||
 | 
					        </Popup>
 | 
				
			||||||
 | 
					        <Button x:Name="Button" Background="#00000000" BorderThickness="0" Foreground="White" Padding="5,0"
 | 
				
			||||||
 | 
					                Template="{StaticResource ResourceKey=TaskbarButton}" Width="28">
 | 
				
			||||||
 | 
					            <Viewbox Stretch="Uniform" Width="Auto">
 | 
				
			||||||
 | 
					                <Canvas Height="18" Width="18">
 | 
				
			||||||
 | 
					                    <Path Stroke="White" Data="M3,6 H17 V9 H18 V11 H17 V9 H17 V14 H3 Z" Panel.ZIndex="2" />
 | 
				
			||||||
 | 
					                    <Rectangle x:Name="BatteryCharge" Canvas.Left="3.5" Canvas.Top="6" Fill="Green" Height="8" Width="13" />
 | 
				
			||||||
 | 
					                    <Grid x:Name="PowerPlug" Panel.ZIndex="3">
 | 
				
			||||||
 | 
					                        <Path Stroke="White" Fill="Black" Data="M2.5,14.5 V10 Q5,10 5,6 H4 V4 H4 V6 H1 V4 H1 V6 H0 Q0,10 2.5,10" Panel.ZIndex="2" />
 | 
				
			||||||
 | 
					                        <Path Stroke="Black" Data="M4,14.5 V10 Q6,10 6,5.5" Panel.ZIndex="1" />
 | 
				
			||||||
 | 
					                    </Grid>
 | 
				
			||||||
 | 
					                    <TextBlock x:Name="Warning" FontSize="18" FontWeight="ExtraBold" Foreground="Red" Canvas.Left="7" Canvas.Top="-3.5" Panel.ZIndex="3">!</TextBlock>
 | 
				
			||||||
 | 
					                </Canvas>
 | 
				
			||||||
 | 
					            </Viewbox>
 | 
				
			||||||
 | 
					        </Button>
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
</UserControl>
 | 
					</UserControl>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,42 +6,70 @@
 | 
				
			||||||
 * 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;
 | 
					 | 
				
			||||||
using System.Windows;
 | 
					using System.Windows;
 | 
				
			||||||
using System.Windows.Controls;
 | 
					using System.Windows.Controls;
 | 
				
			||||||
 | 
					using System.Windows.Media;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.SystemComponents;
 | 
				
			||||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
 | 
					using SafeExamBrowser.Contracts.UserInterface.Taskbar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.UserInterface.Controls
 | 
					namespace SafeExamBrowser.UserInterface.Controls
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public partial class PowerSupplyControl : UserControl, ISystemPowerSupplyControl
 | 
						public partial class PowerSupplyControl : UserControl, ISystemPowerSupplyControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							private double BATTERY_CHARGE_MAX_WIDTH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public PowerSupplyControl()
 | 
							public PowerSupplyControl()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			InitializeComponent();
 | 
								InitializeComponent();
 | 
				
			||||||
			InitializePowerSupplyControl();
 | 
								BATTERY_CHARGE_MAX_WIDTH = BatteryCharge.Width;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void SetBatteryCharge(double? percentage)
 | 
							public void Close()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			throw new NotImplementedException();
 | 
								Popup.IsOpen = false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void SetBatteryCharge(double charge, BatteryChargeStatus status)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Dispatcher.Invoke(() =>
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									BatteryCharge.Width = BATTERY_CHARGE_MAX_WIDTH * charge;
 | 
				
			||||||
 | 
									BatteryCharge.Fill = status == BatteryChargeStatus.Low ? (status == BatteryChargeStatus.Critical ? Brushes.Red : Brushes.Orange) : Brushes.Green;
 | 
				
			||||||
 | 
									Warning.Visibility = status == BatteryChargeStatus.Critical ? Visibility.Visible : Visibility.Collapsed;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void SetPowerGridConnection(bool connected)
 | 
							public void SetPowerGridConnection(bool connected)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			throw new NotImplementedException();
 | 
								Dispatcher.Invoke(() => PowerPlug.Visibility = connected ? Visibility.Visible : Visibility.Collapsed);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void SetTooltip(string text)
 | 
							public void SetTooltip(string text)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			throw new NotImplementedException();
 | 
								Dispatcher.Invoke(() => Button.ToolTip = text);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void InitializePowerSupplyControl()
 | 
							public void ShowCriticalBatteryWarning(string warning)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Button.Resources.MergedDictionaries.Add(new ResourceDictionary
 | 
								Dispatcher.Invoke(() => ShowPopup(warning));
 | 
				
			||||||
			{
 | 
							}
 | 
				
			||||||
				Source = (new Uri("/SafeExamBrowser.UserInterface;component/Styles/ButtonStyles.xaml", UriKind.RelativeOrAbsolute))
 | 
					
 | 
				
			||||||
			});
 | 
							public void ShowLowBatteryInfo(string info)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Dispatcher.Invoke(() => ShowPopup(info));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void ShowPopup(string text)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Popup.IsOpen = true;
 | 
				
			||||||
 | 
								PopupText.Text = text;
 | 
				
			||||||
 | 
								Background = (Brush) new BrushConverter().ConvertFrom("#2AFFFFFF");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Button_Click(object sender, RoutedEventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Popup.IsOpen = false;
 | 
				
			||||||
 | 
								Background = (Brush) new BrushConverter().ConvertFrom("#00000000");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,7 +164,7 @@
 | 
				
			||||||
      <SubType>Designer</SubType>
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
      <Generator>MSBuild:Compile</Generator>
 | 
					      <Generator>MSBuild:Compile</Generator>
 | 
				
			||||||
    </Page>
 | 
					    </Page>
 | 
				
			||||||
    <Page Include="Styles\ButtonStyles.xaml">
 | 
					    <Page Include="Templates\Buttons.xaml">
 | 
				
			||||||
      <SubType>Designer</SubType>
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
      <Generator>MSBuild:Compile</Generator>
 | 
					      <Generator>MSBuild:Compile</Generator>
 | 
				
			||||||
    </Page>
 | 
					    </Page>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,7 @@ namespace SafeExamBrowser.UserInterface
 | 
				
			||||||
			InitializeComponent();
 | 
								InitializeComponent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Loaded += (o, args) => InitializeBounds();
 | 
								Loaded += (o, args) => InitializeBounds();
 | 
				
			||||||
 | 
								Closing += Taskbar_Closing;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void AddApplication(IApplicationButton button)
 | 
							public void AddApplication(IApplicationButton button)
 | 
				
			||||||
| 
						 | 
					@ -76,5 +77,16 @@ namespace SafeExamBrowser.UserInterface
 | 
				
			||||||
				logger.Info($"Set taskbar bounds to {Width}x{Height} at ({Left}/{Top}), in physical pixels: {size.X}x{size.Y} at ({position.X}/{position.Y}).");
 | 
									logger.Info($"Set taskbar bounds to {Width}x{Height} at ({Left}/{Top}), in physical pixels: {size.X}x{size.Y} at ({position.X}/{position.Y}).");
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Taskbar_Closing(object sender, System.ComponentModel.CancelEventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								foreach (var child in SystemControlStackPanel.Children)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (child is ISystemControl)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										(child as ISystemControl).Close();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,7 +78,7 @@ namespace SafeExamBrowser
 | 
				
			||||||
			displayMonitor = new DisplayMonitor(new ModuleLogger(logger, typeof(DisplayMonitor)), nativeMethods);
 | 
								displayMonitor = new DisplayMonitor(new ModuleLogger(logger, typeof(DisplayMonitor)), nativeMethods);
 | 
				
			||||||
			keyboardInterceptor = new KeyboardInterceptor(settings.Keyboard, new ModuleLogger(logger, typeof(KeyboardInterceptor)));
 | 
								keyboardInterceptor = new KeyboardInterceptor(settings.Keyboard, new ModuleLogger(logger, typeof(KeyboardInterceptor)));
 | 
				
			||||||
			mouseInterceptor = new MouseInterceptor(new ModuleLogger(logger, typeof(MouseInterceptor)), settings.Mouse);
 | 
								mouseInterceptor = new MouseInterceptor(new ModuleLogger(logger, typeof(MouseInterceptor)), settings.Mouse);
 | 
				
			||||||
			powerSupply = new PowerSupply(new ModuleLogger(logger, typeof(PowerSupply)));
 | 
								powerSupply = new PowerSupply(new ModuleLogger(logger, typeof(PowerSupply)), text);
 | 
				
			||||||
			processMonitor = new ProcessMonitor(new ModuleLogger(logger, typeof(ProcessMonitor)), nativeMethods);
 | 
								processMonitor = new ProcessMonitor(new ModuleLogger(logger, typeof(ProcessMonitor)), nativeMethods);
 | 
				
			||||||
			windowMonitor = new WindowMonitor(new ModuleLogger(logger, typeof(WindowMonitor)), nativeMethods);
 | 
								windowMonitor = new WindowMonitor(new ModuleLogger(logger, typeof(WindowMonitor)), nativeMethods);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue