SEBWIN-219: Found better solution for session operation sequence (got rid of session controller and sequence start resp. end operations).

This commit is contained in:
dbuechel 2018-03-21 10:23:15 +01:00
parent e750f870c0
commit 6efa7bed81
15 changed files with 270 additions and 246 deletions

View file

@ -43,14 +43,14 @@ namespace SafeExamBrowser.Contracts.I18n
Notification_AboutTooltip,
Notification_LogTooltip,
ProgressIndicator_CloseRuntimeConnection,
ProgressIndicator_CloseServiceConnection,
ProgressIndicator_EmptyClipboard,
ProgressIndicator_FinalizeServiceSession,
ProgressIndicator_InitializeBrowser,
ProgressIndicator_InitializeConfiguration,
ProgressIndicator_InitializeKioskMode,
ProgressIndicator_InitializeProcessMonitoring,
ProgressIndicator_InitializeRuntimeConnection,
ProgressIndicator_InitializeServiceConnection,
ProgressIndicator_InitializeServiceSession,
ProgressIndicator_InitializeTaskbar,
ProgressIndicator_InitializeWindowMonitoring,
ProgressIndicator_InitializeWorkingArea,
@ -58,17 +58,18 @@ namespace SafeExamBrowser.Contracts.I18n
ProgressIndicator_RestoreWorkingArea,
ProgressIndicator_RevertKioskMode,
ProgressIndicator_ShutdownProcedure,
ProgressIndicator_StartClient,
ProgressIndicator_StartCommunicationHost,
ProgressIndicator_StartEventHandling,
ProgressIndicator_StartKeyboardInterception,
ProgressIndicator_StartMouseInterception,
ProgressIndicator_StartSession,
ProgressIndicator_InitializeSession,
ProgressIndicator_StopClient,
ProgressIndicator_StopCommunicationHost,
ProgressIndicator_StopEventHandling,
ProgressIndicator_StopKeyboardInterception,
ProgressIndicator_StopMouseInterception,
ProgressIndicator_StopProcessMonitoring,
ProgressIndicator_StopSession,
ProgressIndicator_StopWindowMonitoring,
ProgressIndicator_TerminateBrowser,
ProgressIndicator_TerminateTaskbar,

View file

@ -81,12 +81,12 @@
<Entry key="ProgressIndicator_CloseRuntimeConnection">
Closing runtime connection
</Entry>
<Entry key="ProgressIndicator_CloseServiceConnection">
Closing service connection
</Entry>
<Entry key="ProgressIndicator_EmptyClipboard">
Emptying clipboard
</Entry>
<Entry key="ProgressIndicator_FinalizeServiceSession">
Finalizing service session
</Entry>
<Entry key="ProgressIndicator_InitializeBrowser">
Initializing browser
</Entry>
@ -102,8 +102,11 @@
<Entry key="ProgressIndicator_InitializeRuntimeConnection">
Initializing runtime connection
</Entry>
<Entry key="ProgressIndicator_InitializeServiceConnection">
Initializing service connection
<Entry key="ProgressIndicator_InitializeServiceSession">
Initializing service session
</Entry>
<Entry key="ProgressIndicator_InitializeSession">
Initializing new session
</Entry>
<Entry key="ProgressIndicator_InitializeTaskbar">
Initializing taskbar
@ -126,6 +129,9 @@
<Entry key="ProgressIndicator_ShutdownProcedure">
Initiating shutdown procedure
</Entry>
<Entry key="ProgressIndicator_StartClient">
Starting client
</Entry>
<Entry key="ProgressIndicator_StartCommunicationHost">
Starting communication host
</Entry>
@ -138,8 +144,8 @@
<Entry key="ProgressIndicator_StartMouseInterception">
Starting mouse interception
</Entry>
<Entry key="ProgressIndicator_StartSession">
Starting new session
<Entry key="ProgressIndicator_StopClient">
Stopping client
</Entry>
<Entry key="ProgressIndicator_StopCommunicationHost">
Stopping communication host
@ -156,9 +162,6 @@
<Entry key="ProgressIndicator_StopProcessMonitoring">
Stopping process monitoring
</Entry>
<Entry key="ProgressIndicator_StopSession">
Stopping current session
</Entry>
<Entry key="ProgressIndicator_StopWindowMonitoring">
Stopping window monitoring
</Entry>

View file

@ -28,7 +28,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
private Mock<IConfigurationRepository> configuration;
private Mock<IProgressIndicator> progressIndicator;
private Mock<IText> text;
private ServiceConnectionOperation sut;
private ServiceOperation sut;
[TestInitialize]
public void Initialize()
@ -39,7 +39,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
progressIndicator = new Mock<IProgressIndicator>();
text = new Mock<IText>();
sut = new ServiceConnectionOperation(configuration.Object, logger.Object, service.Object, text.Object);
sut = new ServiceOperation(configuration.Object, logger.Object, service.Object, text.Object);
}
[TestMethod]

View file

@ -1,22 +0,0 @@
/*
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
{
[TestClass]
public class SessionSequenceOperationTests
{
[TestMethod]
public void TODO()
{
Assert.Fail();
}
}
}

View file

@ -83,7 +83,6 @@
<Compile Include="Behaviour\Operations\ConfigurationOperationTests.cs" />
<Compile Include="Behaviour\Operations\KioskModeOperationTests.cs" />
<Compile Include="Behaviour\Operations\ServiceConnectionOperationTests.cs" />
<Compile Include="Behaviour\Operations\SessionSequenceOperationTests.cs" />
<Compile Include="Behaviour\RuntimeControllerTests.cs" />
<Compile Include="Communication\RuntimeHostTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

View file

@ -17,104 +17,69 @@ using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.UserInterface;
using SafeExamBrowser.Contracts.WindowsApi;
namespace SafeExamBrowser.Runtime.Behaviour
namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
internal class SessionController
internal class ClientOperation : IOperation
{
private const int TEN_SECONDS = 10000;
private bool sessionRunning;
private IConfigurationRepository configuration;
private ILogger logger;
private IProcessFactory processFactory;
private IProxyFactory proxyFactory;
private IRuntimeHost runtimeHost;
private IServiceProxy service;
protected IConfigurationRepository configuration;
protected ILogger logger;
protected IProcessFactory processFactory;
protected IProxyFactory proxyFactory;
protected IRuntimeHost runtimeHost;
internal IProgressIndicator ProgressIndicator { private get; set; }
protected static IProcess ClientProcess { get; private set; }
protected static IClientProxy ClientProxy { get; private set; }
public IProgressIndicator ProgressIndicator { protected get; set; }
internal SessionController(
public ClientOperation(
IConfigurationRepository configuration,
ILogger logger,
IProcessFactory processFactory,
IProxyFactory proxyFactory,
IRuntimeHost runtimeHost,
IServiceProxy service)
IRuntimeHost runtimeHost)
{
this.configuration = configuration;
this.logger = logger;
this.processFactory = processFactory;
this.proxyFactory = proxyFactory;
this.runtimeHost = runtimeHost;
this.service = service;
}
internal OperationResult StartSession()
public virtual OperationResult Perform()
{
logger.Info("Starting new session...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartSession, true);
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartClient, true);
InitializeSessionConfiguration();
StartServiceSession();
sessionRunning = TryStartClient();
var success = TryStartClient();
if (!sessionRunning)
if (success)
{
logger.Info($"Failed to start new session! Reverting service session and aborting procedure...");
service.StopSession(configuration.CurrentSession.Id);
return OperationResult.Failed;
logger.Info($"Successfully started new client instance.");
}
else
{
logger.Error($"Failed to start new client instance! Aborting procedure...");
}
logger.Info($"Successfully started new session.");
return OperationResult.Success;
return success ? OperationResult.Success : OperationResult.Failed;
}
internal OperationResult StopSession()
public virtual OperationResult Repeat()
{
if (sessionRunning)
return Perform();
}
public virtual void Revert()
{
if (ClientProcess != null && !ClientProcess.HasTerminated)
{
logger.Info($"Stopping session with identifier '{configuration.CurrentSession.Id}'...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StopSession, true);
StopServiceSession();
if (!configuration.CurrentSession.ClientProcess.HasTerminated)
{
StopClient();
}
sessionRunning = false;
logger.Info($"Successfully stopped session.");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StopClient, true);
TryStopClient();
}
return OperationResult.Success;
}
private void InitializeSessionConfiguration()
{
configuration.InitializeSessionConfiguration();
runtimeHost.StartupToken = configuration.CurrentSession.StartupToken;
logger.Info($" -> Client-ID: {configuration.RuntimeInfo.ClientId}");
logger.Info($" -> Runtime-ID: {configuration.RuntimeInfo.RuntimeId} (as reference, does not change)");
logger.Info($" -> Session-ID: {configuration.CurrentSession.Id}");
}
private void StartServiceSession()
{
logger.Info("Initializing service session...");
service.StartSession(configuration.CurrentSession.Id, configuration.CurrentSettings);
}
private void StopServiceSession()
{
logger.Info("Stopping service session...");
service.StopSession(configuration.CurrentSession.Id);
}
private bool TryStartClient()
protected bool TryStartClient()
{
var clientReady = false;
var clientReadyEvent = new AutoResetEvent(false);
@ -126,7 +91,7 @@ namespace SafeExamBrowser.Runtime.Behaviour
logger.Info("Starting new client process...");
runtimeHost.ClientReady += clientReadyEventHandler;
configuration.CurrentSession.ClientProcess = processFactory.StartNew(clientExecutable, clientLogFile, hostUri, token);
ClientProcess = processFactory.StartNew(clientExecutable, clientLogFile, hostUri, token);
logger.Info("Waiting for client to complete initialization...");
clientReady = clientReadyEvent.WaitOne(TEN_SECONDS);
@ -140,20 +105,20 @@ namespace SafeExamBrowser.Runtime.Behaviour
}
logger.Info("Client has been successfully started and initialized. Creating communication proxy for client host...");
configuration.CurrentSession.ClientProxy = proxyFactory.CreateClientProxy(configuration.RuntimeInfo.ClientAddress);
ClientProxy = proxyFactory.CreateClientProxy(configuration.RuntimeInfo.ClientAddress);
if (!configuration.CurrentSession.ClientProxy.Connect(configuration.CurrentSession.StartupToken))
if (!ClientProxy.Connect(configuration.CurrentSession.StartupToken))
{
logger.Error("Failed to connect to client!");
return false;
}
logger.Info("Connection with client has been established.");
logger.Info("Connection with client has been established. Requesting authentication...");
var response = configuration.CurrentSession.ClientProxy.RequestAuthentication();
var response = ClientProxy.RequestAuthentication();
if (configuration.CurrentSession.ClientProcess.Id != response?.ProcessId)
if (ClientProcess.Id != response?.ProcessId)
{
logger.Error("Failed to verify client integrity!");
@ -162,11 +127,16 @@ namespace SafeExamBrowser.Runtime.Behaviour
logger.Info("Authentication of client has been successful, client is ready to operate.");
configuration.CurrentSession.ClientProcess = ClientProcess;
configuration.CurrentSession.ClientProxy = ClientProxy;
return true;
}
private void StopClient()
protected bool TryStopClient()
{
var success = false;
var disconnected = false;
var disconnectedEvent = new AutoResetEvent(false);
var disconnectedEventHandler = new CommunicationEventHandler(() => disconnectedEvent.Set());
@ -176,13 +146,13 @@ namespace SafeExamBrowser.Runtime.Behaviour
var terminatedEventHandler = new ProcessTerminatedEventHandler((_) => terminatedEvent.Set());
runtimeHost.ClientDisconnected += disconnectedEventHandler;
configuration.CurrentSession.ClientProcess.Terminated += terminatedEventHandler;
ClientProcess.Terminated += terminatedEventHandler;
logger.Info("Instructing client to initiate shutdown procedure.");
configuration.CurrentSession.ClientProxy.InitiateShutdown();
ClientProxy.InitiateShutdown();
logger.Info("Disconnecting from client communication host.");
configuration.CurrentSession.ClientProxy.Disconnect();
ClientProxy.Disconnect();
logger.Info("Waiting for client to disconnect from runtime communication host...");
disconnected = disconnectedEvent.WaitOne(TEN_SECONDS);
@ -201,20 +171,29 @@ namespace SafeExamBrowser.Runtime.Behaviour
}
runtimeHost.ClientDisconnected -= disconnectedEventHandler;
configuration.CurrentSession.ClientProcess.Terminated -= terminatedEventHandler;
ClientProcess.Terminated -= terminatedEventHandler;
if (disconnected && terminated)
{
logger.Info("Client has been successfully terminated.");
success = true;
}
else
{
logger.Warn("Attempting to kill client process since graceful termination failed!");
KillClient();
success = TryKillClient();
}
if (success)
{
configuration.CurrentSession.ClientProcess = null;
configuration.CurrentSession.ClientProxy = null;
}
return success;
}
private void KillClient(int attempt = 0)
protected bool TryKillClient(int attempt = 0)
{
const int MAX_ATTEMPTS = 5;
@ -222,20 +201,23 @@ namespace SafeExamBrowser.Runtime.Behaviour
{
logger.Error($"Failed to kill client process within {MAX_ATTEMPTS} attempts!");
return;
return false;
}
logger.Info($"Killing client process with ID = {configuration.CurrentSession.ClientProcess.Id}.");
configuration.CurrentSession.ClientProcess.Kill();
logger.Info($"Killing client process with ID = {ClientProcess.Id}.");
ClientProcess.Kill();
if (configuration.CurrentSession.ClientProcess.HasTerminated)
if (ClientProcess.HasTerminated)
{
logger.Info("Client process has terminated.");
return true;
}
else
{
logger.Warn("Failed to kill client process. Trying again...");
KillClient(attempt++);
return TryKillClient(attempt++);
}
}
}

View file

@ -0,0 +1,53 @@
/*
* 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.OperationModel;
using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Communication.Proxies;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.WindowsApi;
namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
internal class ClientTerminationOperation : ClientOperation
{
public ClientTerminationOperation(
IConfigurationRepository configuration,
ILogger logger,
IProcessFactory processFactory,
IProxyFactory proxyFactory,
IRuntimeHost runtimeHost) : base(configuration, logger, processFactory, proxyFactory, runtimeHost)
{
}
public override OperationResult Perform()
{
return OperationResult.Success;
}
public override OperationResult Repeat()
{
var success = true;
if (ClientProcess != null && !ClientProcess.HasTerminated)
{
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StopClient, true);
success = TryStopClient();
}
return success ? OperationResult.Success : OperationResult.Failed;
}
public override void Revert()
{
// Nothing to do here...
}
}
}

View file

@ -23,8 +23,8 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
private IConfigurationRepository repository;
private ILogger logger;
private IMessageBox messageBox;
private RuntimeInfo runtimeInfo;
private IText text;
private RuntimeInfo runtimeInfo;
private string[] commandLineArgs;
public IProgressIndicator ProgressIndicator { private get; set; }
@ -50,30 +50,23 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
logger.Info("Initializing application configuration...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeConfiguration);
Settings settings;
var isValidUri = TryGetSettingsUri(out Uri uri);
if (isValidUri)
{
logger.Info($"Loading configuration from '{uri.AbsolutePath}'...");
settings = repository.LoadSettings(uri);
if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient)
var abort = LoadSettings(uri);
if (abort)
{
var abort = IsConfigurationSufficient();
logger.Info($"The user chose to {(abort ? "abort" : "continue")} after successful client configuration.");
if (abort)
{
return OperationResult.Aborted;
}
return OperationResult.Aborted;
}
}
else
{
logger.Info("No valid settings file specified nor found in PROGRAMDATA or APPDATA - loading default settings...");
settings = repository.LoadDefaultSettings();
repository.LoadDefaultSettings();
}
return OperationResult.Success;
@ -126,6 +119,21 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
return isValidUri;
}
private bool LoadSettings(Uri uri)
{
var abort = false;
var settings = repository.LoadSettings(uri);
if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient)
{
abort = IsConfigurationSufficient();
logger.Info($"The user chose to {(abort ? "abort" : "continue")} after successful client configuration.");
}
return abort;
}
private bool IsConfigurationSufficient()
{
var message = text.Get(TextKey.MessageBox_ClientConfigurationQuestion);

View file

@ -17,7 +17,7 @@ using SafeExamBrowser.Contracts.UserInterface;
namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
internal class ServiceConnectionOperation : IOperation
internal class ServiceOperation : IOperation
{
private bool connected, mandatory;
private IConfigurationRepository configuration;
@ -27,7 +27,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
public IProgressIndicator ProgressIndicator { private get; set; }
public ServiceConnectionOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy service, IText text)
public ServiceOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy service, IText text)
{
this.configuration = configuration;
this.service = service;
@ -37,8 +37,8 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
public OperationResult Perform()
{
logger.Info($"Initializing service connection...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeServiceConnection);
logger.Info($"Initializing service session...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeServiceSession);
try
{
@ -60,23 +60,35 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
service.Ignore = !connected;
logger.Info($"The service is {(mandatory ? "mandatory" : "optional")} and {(connected ? "available." : "not available. All service-related operations will be ignored!")}");
if (connected)
{
StartServiceSession();
}
return OperationResult.Success;
}
public OperationResult Repeat()
{
// TODO: Re-check if mandatory, if so, try to connect (if not connected) - otherwise, no action required (except maybe logging of status?)
if (connected)
{
StopServiceSession();
StartServiceSession();
}
return OperationResult.Success;
}
public void Revert()
{
logger.Info("Closing service connection...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_CloseServiceConnection);
logger.Info("Finalizing service session...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_FinalizeServiceSession);
if (connected)
{
StopServiceSession();
try
{
service.Disconnect();
@ -88,6 +100,16 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
}
}
private void StartServiceSession()
{
service.StartSession(configuration.CurrentSession.Id, configuration.CurrentSettings);
}
private void StopServiceSession()
{
service.StopSession(configuration.CurrentSession.Id);
}
private void LogException(Exception e)
{
var message = "Failed to connect to the service component!";

View file

@ -0,0 +1,65 @@
/*
* 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.OperationModel;
using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.UserInterface;
namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
internal class SessionInitializationOperation : IOperation
{
private IConfigurationRepository configuration;
private ILogger logger;
private IRuntimeHost runtimeHost;
public IProgressIndicator ProgressIndicator { private get; set; }
public SessionInitializationOperation(IConfigurationRepository configuration, ILogger logger, IRuntimeHost runtimeHost)
{
this.configuration = configuration;
this.logger = logger;
this.runtimeHost = runtimeHost;
}
public OperationResult Perform()
{
InitializeSessionConfiguration();
return OperationResult.Success;
}
public OperationResult Repeat()
{
InitializeSessionConfiguration();
return OperationResult.Success;
}
public void Revert()
{
// Nothing to do here...
}
private void InitializeSessionConfiguration()
{
logger.Info("Initializing new session configuration...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeSession, true);
configuration.InitializeSessionConfiguration();
runtimeHost.StartupToken = configuration.CurrentSession.StartupToken;
logger.Info($" -> Client-ID: {configuration.RuntimeInfo.ClientId}");
logger.Info($" -> Runtime-ID: {configuration.RuntimeInfo.RuntimeId} (as reference, does not change)");
logger.Info($" -> Session-ID: {configuration.CurrentSession.Id}");
}
}
}

View file

@ -1,45 +0,0 @@
/*
* 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.OperationModel;
using SafeExamBrowser.Contracts.UserInterface;
namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
internal class SessionSequenceEndOperation : IOperation
{
private SessionController controller;
public IProgressIndicator ProgressIndicator { private get; set; }
public SessionSequenceEndOperation(SessionController controller)
{
this.controller = controller;
}
public OperationResult Perform()
{
controller.ProgressIndicator = ProgressIndicator;
return controller.StartSession();
}
public OperationResult Repeat()
{
controller.ProgressIndicator = ProgressIndicator;
return controller.StartSession();
}
public void Revert()
{
controller.ProgressIndicator = ProgressIndicator;
controller.StopSession();
}
}
}

View file

@ -1,42 +0,0 @@
/*
* 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.OperationModel;
using SafeExamBrowser.Contracts.UserInterface;
namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
internal class SessionSequenceStartOperation : IOperation
{
private SessionController controller;
public IProgressIndicator ProgressIndicator { private get; set; }
public SessionSequenceStartOperation(SessionController controller)
{
this.controller = controller;
}
public OperationResult Perform()
{
return OperationResult.Success;
}
public OperationResult Repeat()
{
controller.ProgressIndicator = ProgressIndicator;
return controller.StopSession();
}
public void Revert()
{
// Nothing to do here...
}
}
}

View file

@ -209,18 +209,18 @@ namespace SafeExamBrowser.Runtime.Behaviour
runtimeHost.ShutdownRequested += RuntimeHost_ShutdownRequested;
}
private void RegisterSessionEvents()
{
configuration.CurrentSession.ClientProcess.Terminated += ClientProcess_Terminated;
configuration.CurrentSession.ClientProxy.ConnectionLost += Client_ConnectionLost;
}
private void DeregisterEvents()
{
runtimeHost.ReconfigurationRequested -= RuntimeHost_ReconfigurationRequested;
runtimeHost.ShutdownRequested -= RuntimeHost_ShutdownRequested;
}
private void RegisterSessionEvents()
{
configuration.CurrentSession.ClientProcess.Terminated += ClientProcess_Terminated;
configuration.CurrentSession.ClientProxy.ConnectionLost += Client_ConnectionLost;
}
private void DeregisterSessionEvents()
{
configuration.CurrentSession.ClientProcess.Terminated -= ClientProcess_Terminated;

View file

@ -54,7 +54,6 @@ namespace SafeExamBrowser.Runtime
var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), logger);
var runtimeHost = new RuntimeHost(runtimeInfo.RuntimeAddress, configuration, new HostObjectFactory(), new ModuleLogger(logger, typeof(RuntimeHost)));
var serviceProxy = new ServiceProxy(runtimeInfo.ServiceAddress, new ProxyObjectFactory(), new ModuleLogger(logger, typeof(ServiceProxy)));
var sessionController = new SessionController(configuration, logger, processFactory, proxyFactory, runtimeHost, serviceProxy);
var bootstrapOperations = new Queue<IOperation>();
var sessionOperations = new Queue<IOperation>();
@ -62,16 +61,17 @@ namespace SafeExamBrowser.Runtime
bootstrapOperations.Enqueue(new I18nOperation(logger, text));
bootstrapOperations.Enqueue(new CommunicationOperation(runtimeHost, logger));
sessionOperations.Enqueue(new SessionSequenceStartOperation(sessionController));
sessionOperations.Enqueue(new ConfigurationOperation(configuration, logger, messageBox, runtimeInfo, text, args));
sessionOperations.Enqueue(new ServiceConnectionOperation(configuration, logger, serviceProxy, text));
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost));
sessionOperations.Enqueue(new ServiceOperation(configuration, logger, serviceProxy, text));
sessionOperations.Enqueue(new ClientTerminationOperation(configuration, logger, processFactory, proxyFactory, runtimeHost));
sessionOperations.Enqueue(new KioskModeOperation(logger, configuration));
sessionOperations.Enqueue(new SessionSequenceEndOperation(sessionController));
sessionOperations.Enqueue(new ClientOperation(configuration, logger, processFactory, proxyFactory, runtimeHost));
var boostrapSequence = new OperationSequence(logger, bootstrapOperations);
var bootstrapSequence = new OperationSequence(logger, bootstrapOperations);
var sessionSequence = new OperationSequence(logger, sessionOperations);
RuntimeController = new RuntimeController(configuration, logger, messageBox, boostrapSequence, sessionSequence, runtimeHost, runtimeInfo, serviceProxy, shutdown, uiFactory);
RuntimeController = new RuntimeController(configuration, logger, messageBox, bootstrapSequence, sessionSequence, runtimeHost, runtimeInfo, serviceProxy, shutdown, uiFactory);
}
internal void LogStartupInformation()

View file

@ -87,12 +87,12 @@
</ItemGroup>
<ItemGroup>
<Compile Include="App.cs" />
<Compile Include="Behaviour\Operations\ClientOperation.cs" />
<Compile Include="Behaviour\Operations\ClientTerminationOperation.cs" />
<Compile Include="Behaviour\Operations\ConfigurationOperation.cs" />
<Compile Include="Behaviour\Operations\KioskModeOperation.cs" />
<Compile Include="Behaviour\Operations\ServiceConnectionOperation.cs" />
<Compile Include="Behaviour\Operations\SessionSequenceEndOperation.cs" />
<Compile Include="Behaviour\SessionController.cs" />
<Compile Include="Behaviour\Operations\SessionSequenceStartOperation.cs" />
<Compile Include="Behaviour\Operations\ServiceOperation.cs" />
<Compile Include="Behaviour\Operations\SessionInitializationOperation.cs" />
<Compile Include="Communication\ProxyFactory.cs" />
<Compile Include="Communication\RuntimeHost.cs" />
<Compile Include="CompositionRoot.cs" />