From 66e9078a4c75d7c5226a171f1600c79dfc7a3a21 Mon Sep 17 00:00:00 2001 From: dbuechel Date: Thu, 8 Feb 2018 13:32:48 +0100 Subject: [PATCH] SEBWIN-219: Implemented draft of session mechanism. --- .../ConfigurationRepository.cs | 12 +++ .../SafeExamBrowser.Configuration.csproj | 1 + SafeExamBrowser.Configuration/SessionData.cs | 19 +++++ .../Communication/IClientProxy.cs | 8 ++ .../Communication/IServiceProxy.cs | 13 ++++ .../Configuration/IConfigurationRepository.cs | 11 +++ .../Configuration/ISessionData.cs | 20 +++++ SafeExamBrowser.Contracts/I18n/TextKey.cs | 4 +- .../SafeExamBrowser.Contracts.csproj | 1 + .../Communication/BaseHost.cs | 35 ++++++++- .../Communication/ServiceProxy.cs | 42 ++++++++-- SafeExamBrowser.Core/I18n/Text.xml | 12 +-- .../Operations/ConfigurationOperation.cs | 1 + .../Operations/SessionSequenceEndOperation.cs | 36 +++++++++ .../Operations/SessionSequenceOperation.cs | 76 +++++++++++++++++++ .../SessionSequenceStartOperation.cs | 36 +++++++++ .../Behaviour/RuntimeController.cs | 46 +++-------- .../Communication/RuntimeHost.cs | 6 +- SafeExamBrowser.Runtime/CompositionRoot.cs | 9 ++- .../SafeExamBrowser.Runtime.csproj | 3 + .../RuntimeWindow.xaml | 2 +- 21 files changed, 334 insertions(+), 59 deletions(-) create mode 100644 SafeExamBrowser.Configuration/SessionData.cs create mode 100644 SafeExamBrowser.Contracts/Configuration/ISessionData.cs create mode 100644 SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceEndOperation.cs create mode 100644 SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceOperation.cs create mode 100644 SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceStartOperation.cs diff --git a/SafeExamBrowser.Configuration/ConfigurationRepository.cs b/SafeExamBrowser.Configuration/ConfigurationRepository.cs index 84853c52..ece6003e 100644 --- a/SafeExamBrowser.Configuration/ConfigurationRepository.cs +++ b/SafeExamBrowser.Configuration/ConfigurationRepository.cs @@ -18,6 +18,7 @@ namespace SafeExamBrowser.Configuration { private RuntimeInfo runtimeInfo; + public ISessionData CurrentSessionData { get; private set; } public ISettings CurrentSettings { get; private set; } public IRuntimeInfo RuntimeInfo @@ -33,6 +34,17 @@ namespace SafeExamBrowser.Configuration } } + public ISessionData InitializeSessionData() + { + var sessionData = new SessionData(); + + sessionData.Id = Guid.NewGuid(); + + CurrentSessionData = sessionData; + + return sessionData; + } + public ISettings LoadSettings(Uri path) { // TODO diff --git a/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj b/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj index d1e7b694..770e8af2 100644 --- a/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj +++ b/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj @@ -54,6 +54,7 @@ + diff --git a/SafeExamBrowser.Configuration/SessionData.cs b/SafeExamBrowser.Configuration/SessionData.cs new file mode 100644 index 00000000..508cc3fc --- /dev/null +++ b/SafeExamBrowser.Configuration/SessionData.cs @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using SafeExamBrowser.Contracts.Configuration; + +namespace SafeExamBrowser.Configuration +{ + [Serializable] + public class SessionData : ISessionData + { + public Guid Id { get; set; } + } +} diff --git a/SafeExamBrowser.Contracts/Communication/IClientProxy.cs b/SafeExamBrowser.Contracts/Communication/IClientProxy.cs index 26350cc2..65d8bee5 100644 --- a/SafeExamBrowser.Contracts/Communication/IClientProxy.cs +++ b/SafeExamBrowser.Contracts/Communication/IClientProxy.cs @@ -12,6 +12,14 @@ namespace SafeExamBrowser.Contracts.Communication { public interface IClientProxy { + /// + /// Tries to connect to the client host. + /// bool Connect(Guid token); + + /// + /// Disconnects from the client host. + /// + void Disconnect(); } } diff --git a/SafeExamBrowser.Contracts/Communication/IServiceProxy.cs b/SafeExamBrowser.Contracts/Communication/IServiceProxy.cs index 4cc033b6..ac49944a 100644 --- a/SafeExamBrowser.Contracts/Communication/IServiceProxy.cs +++ b/SafeExamBrowser.Contracts/Communication/IServiceProxy.cs @@ -6,6 +6,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +using System; +using SafeExamBrowser.Contracts.Configuration.Settings; + namespace SafeExamBrowser.Contracts.Communication { public interface IServiceProxy @@ -25,5 +28,15 @@ namespace SafeExamBrowser.Contracts.Communication /// Disconnects from the service host. /// void Disconnect(); + + /// + /// Instructs the service to start a new session according to the given parameters. + /// + void StartSession(Guid sessionId, ISettings settings); + + /// + /// Instructs the service to stop the specified session. + /// + void StopSession(Guid sessionId); } } diff --git a/SafeExamBrowser.Contracts/Configuration/IConfigurationRepository.cs b/SafeExamBrowser.Contracts/Configuration/IConfigurationRepository.cs index baa652b2..69e85199 100644 --- a/SafeExamBrowser.Contracts/Configuration/IConfigurationRepository.cs +++ b/SafeExamBrowser.Contracts/Configuration/IConfigurationRepository.cs @@ -13,6 +13,12 @@ namespace SafeExamBrowser.Contracts.Configuration { public interface IConfigurationRepository { + /// + /// Retrieves the current session data, i.e. the last ones which were initialized. If no session has been initialized yet, this + /// property will be null! + /// + ISessionData CurrentSessionData { get; } + /// /// Retrieves the current settings, i.e. the last ones which were loaded. If no settings have been loaded yet, this property will /// be null! @@ -24,6 +30,11 @@ namespace SafeExamBrowser.Contracts.Configuration /// IRuntimeInfo RuntimeInfo { get; } + /// + /// Initializes all relevant data for a new session. + /// + ISessionData InitializeSessionData(); + /// /// Attempts to load settings from the specified path. /// diff --git a/SafeExamBrowser.Contracts/Configuration/ISessionData.cs b/SafeExamBrowser.Contracts/Configuration/ISessionData.cs new file mode 100644 index 00000000..7a6335a7 --- /dev/null +++ b/SafeExamBrowser.Contracts/Configuration/ISessionData.cs @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018 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; + +namespace SafeExamBrowser.Contracts.Configuration +{ + public interface ISessionData + { + /// + /// The unique session identifier. + /// + Guid Id { get; } + } +} diff --git a/SafeExamBrowser.Contracts/I18n/TextKey.cs b/SafeExamBrowser.Contracts/I18n/TextKey.cs index 73c09d35..27f5a142 100644 --- a/SafeExamBrowser.Contracts/I18n/TextKey.cs +++ b/SafeExamBrowser.Contracts/I18n/TextKey.cs @@ -45,19 +45,19 @@ namespace SafeExamBrowser.Contracts.I18n ProgressIndicator_StartEventHandling, ProgressIndicator_StartKeyboardInterception, ProgressIndicator_StartMouseInterception, + ProgressIndicator_StartSession, ProgressIndicator_StopCommunicationHost, ProgressIndicator_StopEventHandling, ProgressIndicator_StopKeyboardInterception, ProgressIndicator_StopMouseInterception, ProgressIndicator_StopProcessMonitoring, + ProgressIndicator_StopSession, ProgressIndicator_StopWindowMonitoring, ProgressIndicator_TerminateBrowser, ProgressIndicator_TerminateTaskbar, ProgressIndicator_WaitExplorerStartup, ProgressIndicator_WaitExplorerTermination, RuntimeWindow_ApplicationRunning, - RuntimeWindow_StartSession, - RuntimeWindow_StopSession, SystemControl_BatteryCharged, SystemControl_BatteryCharging, SystemControl_BatteryChargeCriticalWarning, diff --git a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj index b851b8a1..d41c12c2 100644 --- a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj +++ b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj @@ -66,6 +66,7 @@ + diff --git a/SafeExamBrowser.Core/Communication/BaseHost.cs b/SafeExamBrowser.Core/Communication/BaseHost.cs index 4940fb17..0f34ba8b 100644 --- a/SafeExamBrowser.Core/Communication/BaseHost.cs +++ b/SafeExamBrowser.Core/Communication/BaseHost.cs @@ -33,9 +33,38 @@ namespace SafeExamBrowser.Core.Communication this.logger = logger; } - public abstract IConnectResponse Connect(Guid? token = null); - public abstract void Disconnect(IMessage message); - public abstract IResponse Send(IMessage message); + protected abstract IConnectResponse OnConnect(Guid? token); + protected abstract void OnDisconnect(IMessage message); + protected abstract IResponse OnReceive(IMessage message); + + public IConnectResponse Connect(Guid? token = null) + { + logger.Debug($"Received connection request with token '{token}'."); + + var response = OnConnect(token); + + logger.Debug($"{(response.ConnectionEstablished ? "Accepted" : "Denied")} connection request."); + + return response; + } + + public void Disconnect(IMessage message) + { + logger.Debug($"Received disconnection request with message '{message}'."); + + OnDisconnect(message); + } + + public IResponse Send(IMessage message) + { + logger.Debug($"Received message '{message}'."); + + var response = OnReceive(message); + + logger.Debug($"Sending response '{response}'."); + + return response; + } public void Start() { diff --git a/SafeExamBrowser.Core/Communication/ServiceProxy.cs b/SafeExamBrowser.Core/Communication/ServiceProxy.cs index 8654d33c..0a79b14d 100644 --- a/SafeExamBrowser.Core/Communication/ServiceProxy.cs +++ b/SafeExamBrowser.Core/Communication/ServiceProxy.cs @@ -6,7 +6,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +using System; using SafeExamBrowser.Contracts.Communication; +using SafeExamBrowser.Contracts.Configuration.Settings; using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Core.Communication.Messages; @@ -22,22 +24,48 @@ namespace SafeExamBrowser.Core.Communication public bool Connect() { - if (!IgnoreOperation(nameof(Connect))) + if (IgnoreOperation(nameof(Connect))) { - return base.Connect().ConnectionEstablished; + return false; } - return false; + return base.Connect().ConnectionEstablished; } public void Disconnect() { - if (!IgnoreOperation(nameof(Disconnect))) + if (IgnoreOperation(nameof(Disconnect))) { - FailIfNotConnected(nameof(Disconnect)); - - Disconnect(new Message { CommunicationToken = CommunicationToken.Value }); + return; } + + FailIfNotConnected(nameof(Disconnect)); + + Disconnect(new Message { CommunicationToken = CommunicationToken.Value }); + } + + public void StartSession(Guid sessionId, ISettings settings) + { + if (IgnoreOperation(nameof(StartSession))) + { + return; + } + + FailIfNotConnected(nameof(StartSession)); + + // TODO: Send(new StartSessionMessage { Id = sessionId, Settings = settings }); + } + + public void StopSession(Guid sessionId) + { + if (IgnoreOperation(nameof(StopSession))) + { + return; + } + + FailIfNotConnected(nameof(StopSession)); + + // TODO } private bool IgnoreOperation(string operationName) diff --git a/SafeExamBrowser.Core/I18n/Text.xml b/SafeExamBrowser.Core/I18n/Text.xml index c5737c30..f3b1262a 100644 --- a/SafeExamBrowser.Core/I18n/Text.xml +++ b/SafeExamBrowser.Core/I18n/Text.xml @@ -90,6 +90,9 @@ Starting mouse interception + + Starting new session + Stopping communication host @@ -105,6 +108,9 @@ Stopping process monitoring + + Stopping current session + Stopping window monitoring @@ -123,12 +129,6 @@ The application is running. - - Starting new session - - - Stopping current session - Plugged in, charging... (%%CHARGE%%%) diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs index c492ba24..e54a6336 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs @@ -74,6 +74,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations public void Repeat() { // TODO: How will the new settings be retrieved? Uri passed to the repository? If yes, how does the Uri get here?! + // -> IDEA: Use configuration repository as container? } public void Revert() diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceEndOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceEndOperation.cs new file mode 100644 index 00000000..30173ad4 --- /dev/null +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceEndOperation.cs @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 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.Communication; +using SafeExamBrowser.Contracts.Configuration; +using SafeExamBrowser.Contracts.Logging; + +namespace SafeExamBrowser.Runtime.Behaviour.Operations +{ + internal class SessionSequenceEndOperation : SessionSequenceOperation + { + public SessionSequenceEndOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy serviceProxy) : base(configuration, logger, serviceProxy) + { + } + + public override void Perform() + { + StartSession(); + } + + public override void Repeat() + { + StartSession(); + } + + public override void Revert() + { + StopSession(); + } + } +} diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceOperation.cs new file mode 100644 index 00000000..4236270a --- /dev/null +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceOperation.cs @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018 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.Behaviour.Operations; +using SafeExamBrowser.Contracts.Communication; +using SafeExamBrowser.Contracts.Configuration; +using SafeExamBrowser.Contracts.I18n; +using SafeExamBrowser.Contracts.Logging; +using SafeExamBrowser.Contracts.UserInterface; + +namespace SafeExamBrowser.Runtime.Behaviour.Operations +{ + internal abstract class SessionSequenceOperation : IOperation + { + private bool sessionInitialized; + private IConfigurationRepository configuration; + private ILogger logger; + private IServiceProxy serviceProxy; + private ISessionData sessionData; + + public bool Abort { get; private set; } + public IProgressIndicator ProgressIndicator { private get; set; } + + public SessionSequenceOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy serviceProxy) + { + this.configuration = configuration; + this.logger = logger; + this.serviceProxy = serviceProxy; + } + + public abstract void Perform(); + public abstract void Repeat(); + public abstract void Revert(); + + protected void StartSession() + { + logger.Info("Starting new session..."); + ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartSession, true); + + sessionData = configuration.InitializeSessionData(); + serviceProxy.StartSession(sessionData.Id, configuration.CurrentSettings); + + // TODO: + // - Create and connect to client + // - Verify session integrity and start event handling -> in runtime controller? + System.Threading.Thread.Sleep(5000); + + sessionInitialized = true; + logger.Info($"Successfully started new session with identifier '{sessionData.Id}'."); + } + + protected void StopSession() + { + if (sessionInitialized) + { + logger.Info($"Stopping session with identifier '{sessionData.Id}'..."); + ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StopSession, true); + + serviceProxy.StopSession(sessionData.Id); + + // TODO: + // - Terminate client (or does it terminate itself?) + // - Stop event handling and verify session termination -> in runtime controller? + System.Threading.Thread.Sleep(5000); + + sessionInitialized = false; + logger.Info($"Successfully stopped session with identifier '{sessionData.Id}'."); + } + } + } +} diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceStartOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceStartOperation.cs new file mode 100644 index 00000000..91f953b8 --- /dev/null +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/SessionSequenceStartOperation.cs @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 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.Communication; +using SafeExamBrowser.Contracts.Configuration; +using SafeExamBrowser.Contracts.Logging; + +namespace SafeExamBrowser.Runtime.Behaviour.Operations +{ + internal class SessionSequenceStartOperation : SessionSequenceOperation + { + public SessionSequenceStartOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy serviceProxy) : base(configuration, logger, serviceProxy) + { + } + + public override void Perform() + { + // Nothing to do here... + } + + public override void Repeat() + { + StopSession(); + } + + public override void Revert() + { + // Nothing to do here... + } + } +} diff --git a/SafeExamBrowser.Runtime/Behaviour/RuntimeController.cs b/SafeExamBrowser.Runtime/Behaviour/RuntimeController.cs index e1414dd3..5f0636e4 100644 --- a/SafeExamBrowser.Runtime/Behaviour/RuntimeController.cs +++ b/SafeExamBrowser.Runtime/Behaviour/RuntimeController.cs @@ -20,7 +20,7 @@ namespace SafeExamBrowser.Runtime.Behaviour { internal class RuntimeController : IRuntimeController { - private bool initialized; + private bool sessionRunning; private IConfigurationRepository configuration; private ILogger logger; @@ -68,7 +68,7 @@ namespace SafeExamBrowser.Runtime.Behaviour splashScreen.Show(); - initialized = bootstrapSequence.TryPerform(); + var initialized = bootstrapSequence.TryPerform(); if (initialized) { @@ -86,20 +86,16 @@ namespace SafeExamBrowser.Runtime.Behaviour logger.Log(string.Empty); } - return initialized; + return initialized && sessionRunning; } public void Terminate() { - // TODO: Necessary here? Move to App.cs as private "started" flag if not... - if (!initialized) + if (sessionRunning) { - return; + StopSession(); } - // TODO: Only if session is running! - StopSession(); - logger.Unsubscribe(runtimeWindow); runtimeWindow?.Close(); splashScreen?.Show(); @@ -129,23 +125,12 @@ namespace SafeExamBrowser.Runtime.Behaviour private void StartSession(bool initial = false) { - logger.Info("Starting new session..."); - - runtimeWindow.UpdateText(TextKey.RuntimeWindow_StartSession, true); runtimeWindow.Show(); - var success = initial ? sessionSequence.TryPerform() : sessionSequence.TryRepeat(); + sessionRunning = initial ? sessionSequence.TryPerform() : sessionSequence.TryRepeat(); - if (success) + if (sessionRunning) { - // TODO: - // - Initialize session data - // - Create and connect to client - // - Initialize session with service - // - Verify session integrity and start event handling - - - runtimeWindow.HideProgressBar(); runtimeWindow.UpdateText(TextKey.RuntimeWindow_ApplicationRunning); @@ -157,34 +142,27 @@ namespace SafeExamBrowser.Runtime.Behaviour else { uiFactory.Show(TextKey.MessageBox_SessionStartError, TextKey.MessageBox_SessionStartErrorTitle, icon: MessageBoxIcon.Error); + logger.Info($"Failed to start new session. Terminating application..."); - if (initial) + if (!initial) { - initialized = false; - } - else - { - shutdown(); + shutdown.Invoke(); } } } private void StopSession() { - logger.Info("Stopping current session..."); runtimeWindow.Show(); runtimeWindow.BringToForeground(); runtimeWindow.ShowProgressBar(); - runtimeWindow.UpdateText(TextKey.RuntimeWindow_StopSession, true); - // TODO: - // - Terminate client (or does it terminate itself?) - // - Finalize session with service - // - Stop event handling and close session var success = sessionSequence.TryRevert(); if (success) { + sessionRunning = false; + // TODO } else diff --git a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs index 74e03098..06ea256f 100644 --- a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs +++ b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs @@ -21,19 +21,19 @@ namespace SafeExamBrowser.Runtime.Communication { } - public override IConnectResponse Connect(Guid? token = null) + protected override IConnectResponse OnConnect(Guid? token = null) { // TODO throw new NotImplementedException(); } - public override void Disconnect(IMessage message) + protected override void OnDisconnect(IMessage message) { // TODO throw new NotImplementedException(); } - public override IResponse Send(IMessage message) + protected override IResponse OnReceive(IMessage message) { // TODO throw new NotImplementedException(); diff --git a/SafeExamBrowser.Runtime/CompositionRoot.cs b/SafeExamBrowser.Runtime/CompositionRoot.cs index cf04ca40..7d5efe0a 100644 --- a/SafeExamBrowser.Runtime/CompositionRoot.cs +++ b/SafeExamBrowser.Runtime/CompositionRoot.cs @@ -37,10 +37,8 @@ namespace SafeExamBrowser.Runtime internal void BuildObjectGraph() { var args = Environment.GetCommandLineArgs(); - var bootstrapOperations = new Queue(); - var sessionOperations = new Queue(); - var nativeMethods = new NativeMethods(); var configuration = new ConfigurationRepository(); + var nativeMethods = new NativeMethods(); logger = new Logger(); runtimeInfo = configuration.RuntimeInfo; @@ -53,12 +51,17 @@ namespace SafeExamBrowser.Runtime var runtimeHost = new RuntimeHost(runtimeInfo.RuntimeAddress, new ModuleLogger(logger, typeof(RuntimeHost))); var serviceProxy = new ServiceProxy(runtimeInfo.ServiceAddress, new ModuleLogger(logger, typeof(ServiceProxy))); + var bootstrapOperations = new Queue(); + var sessionOperations = new Queue(); + bootstrapOperations.Enqueue(new I18nOperation(logger, text)); bootstrapOperations.Enqueue(new CommunicationOperation(runtimeHost, logger)); + sessionOperations.Enqueue(new SessionSequenceStartOperation(configuration, logger, serviceProxy)); sessionOperations.Enqueue(new ConfigurationOperation(configuration, logger, runtimeInfo, text, uiFactory, args)); sessionOperations.Enqueue(new ServiceOperation(configuration, logger, serviceProxy, text)); sessionOperations.Enqueue(new KioskModeOperation(logger, configuration)); + sessionOperations.Enqueue(new SessionSequenceEndOperation(configuration, logger, serviceProxy)); var boostrapSequence = new OperationSequence(logger, bootstrapOperations); var sessionSequence = new OperationSequence(logger, sessionOperations); diff --git a/SafeExamBrowser.Runtime/SafeExamBrowser.Runtime.csproj b/SafeExamBrowser.Runtime/SafeExamBrowser.Runtime.csproj index 6b5764f0..050d4535 100644 --- a/SafeExamBrowser.Runtime/SafeExamBrowser.Runtime.csproj +++ b/SafeExamBrowser.Runtime/SafeExamBrowser.Runtime.csproj @@ -90,6 +90,9 @@ + + + diff --git a/SafeExamBrowser.UserInterface.Classic/RuntimeWindow.xaml b/SafeExamBrowser.UserInterface.Classic/RuntimeWindow.xaml index 78bef994..f2d038ff 100644 --- a/SafeExamBrowser.UserInterface.Classic/RuntimeWindow.xaml +++ b/SafeExamBrowser.UserInterface.Classic/RuntimeWindow.xaml @@ -52,7 +52,7 @@ 5 5 - +