SEBWIN-301: Moved ServiceOperation in session sequence of runtime to be able to interact with the user and consolidated KioskModeTerminationOperation into KioskModeOperation itself.

This commit is contained in:
dbuechel 2019-06-12 08:46:10 +02:00
parent 97bf224b37
commit 77a3b50ca9
11 changed files with 175 additions and 420 deletions

View file

@ -259,6 +259,11 @@ namespace SafeExamBrowser.Client
if (communication.Success)
{
logger.Info($"Sent reconfiguration request for '{filePath}' to the runtime.");
splashScreen = uiFactory.CreateSplashScreen(appConfig);
splashScreen.SetIndeterminate();
splashScreen.UpdateStatus(TextKey.OperationStatus_InitializeSession, true);
splashScreen.Show();
}
else
{
@ -277,7 +282,7 @@ namespace SafeExamBrowser.Client
{
logger.Info($"Received message box request with id '{args.RequestId}'.");
var result = messageBox.Show(args.Message, args.Title, args.Action, args.Icon);
var result = messageBox.Show(args.Message, args.Title, args.Action, args.Icon, parent: splashScreen);
runtime.SubmitMessageBoxResult(args.RequestId, result);
logger.Info($"Message box request with id '{args.RequestId}' yielded result '{result}'.");
@ -311,12 +316,18 @@ namespace SafeExamBrowser.Client
runtime.SubmitPassword(args.RequestId, result.Success, result.Password);
logger.Info($"Password request with id '{args.RequestId}' was {(result.Success ? "successful" : "aborted by the user")}.");
if (!result.Success)
{
splashScreen?.Close();
}
}
private void ClientHost_ReconfigurationDenied(ReconfigurationEventArgs args)
{
logger.Info($"The reconfiguration request for '{args.ConfigurationPath}' was denied by the runtime!");
messageBox.Show(TextKey.MessageBox_ReconfigurationDenied, TextKey.MessageBox_ReconfigurationDeniedTitle);
messageBox.Show(TextKey.MessageBox_ReconfigurationDenied, TextKey.MessageBox_ReconfigurationDeniedTitle, parent: splashScreen);
splashScreen?.Close();
}
private void ClientHost_Shutdown()

View file

@ -145,7 +145,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
settings.Mouse.AllowMiddleButton = false;
settings.Mouse.AllowRightButton = true;
settings.ServicePolicy = ServicePolicy.Optional;
settings.ServicePolicy = ServicePolicy.Mandatory;
settings.AllowApplicationLogAccess = false;

View file

@ -103,13 +103,13 @@
Reload?
</Entry>
<Entry key="MessageBox_ServiceUnavailableError">
Failed to initialize the Safe Exam Browser service! The application is not allowed to start since the current configuration requires the service to be running.
Failed to initialize the SEB service! The application will now terminate since the service is configured to be mandatory.
</Entry>
<Entry key="MessageBox_ServiceUnavailableErrorTitle">
Service Unavailable
</Entry>
<Entry key="MessageBox_ServiceUnavailableWarning">
Failed to initialize the Safe Exam Browser service. The application is allowed to start, but it should be ensured that the service is installed and running.
Failed to initialize the SEB service. The application will continue initialization since the service is configured to be optional.
</Entry>
<Entry key="MessageBox_ServiceUnavailableWarningTitle">
Service Unavailable

View file

@ -54,7 +54,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
}
[TestMethod]
public void MustCorrectlyInitializeCreateNewDesktop()
public void Perform_MustCorrectlyInitializeCreateNewDesktop()
{
var originalDesktop = new Mock<IDesktop>();
var newDesktop = new Mock<IDesktop>();
@ -73,7 +73,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
processFactory.SetupSet(f => f.StartupDesktop = It.IsAny<IDesktop>()).Callback(() => setStartup = ++order);
explorerShell.Setup(s => s.Suspend()).Callback(() => suspend = ++order);
sut.Perform();
var result = sut.Perform();
desktopFactory.Verify(f => f.GetCurrent(), Times.Once);
desktopFactory.Verify(f => f.CreateNew(It.IsAny<string>()), Times.Once);
@ -83,8 +83,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
explorerShell.Verify(s => s.Terminate(), Times.Never);
explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
Assert.AreSame(sessionContext.NewDesktop, newDesktop.Object);
Assert.AreSame(sessionContext.OriginalDesktop, originalDesktop.Object);
Assert.AreEqual(OperationResult.Success, result);
Assert.AreEqual(1, getCurrrent);
Assert.AreEqual(2, createNew);
Assert.AreEqual(3, activate);
@ -93,7 +93,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
}
[TestMethod]
public void MustCorrectlyInitializeDisableExplorerShell()
public void Perform_MustCorrectlyInitializeDisableExplorerShell()
{
var order = 0;
@ -101,14 +101,129 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
explorerShell.Setup(s => s.HideAllWindows()).Callback(() => Assert.AreEqual(1, ++order));
explorerShell.Setup(s => s.Terminate()).Callback(() => Assert.AreEqual(2, ++order));
sut.Perform();
var result = sut.Perform();
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
explorerShell.Verify(s => s.Terminate(), Times.Once);
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]
public void MustCorrectlyRevertCreateNewDesktop()
public void Repeat_MustCorrectlySwitchToNewKioskMode()
{
var newDesktop = new Mock<IDesktop>();
var originalDesktop = new Mock<IDesktop>();
var result = default(OperationResult);
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object);
desktopFactory.Setup(f => f.CreateNew(It.IsAny<string>())).Returns(newDesktop.Object);
nextSettings.KioskMode = KioskMode.CreateNewDesktop;
result = sut.Perform();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Terminate(), Times.Never);
explorerShell.Verify(s => s.Start(), Times.Never);
explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Suspend(), Times.Once);
explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Once);
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
nextSettings.KioskMode = KioskMode.DisableExplorerShell;
result = sut.Repeat();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Terminate(), Times.Once);
explorerShell.Verify(s => s.Start(), Times.Never);
explorerShell.Verify(s => s.Resume(), Times.Once);
explorerShell.Verify(s => s.Suspend(), Times.Once);
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Once);
newDesktop.Verify(d => d.Close(), Times.Once);
originalDesktop.Verify(d => d.Activate(), Times.Once);
currentSettings.KioskMode = nextSettings.KioskMode;
nextSettings.KioskMode = KioskMode.CreateNewDesktop;
result = sut.Repeat();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Terminate(), Times.Once);
explorerShell.Verify(s => s.Start(), Times.Once);
explorerShell.Verify(s => s.Resume(), Times.Once);
explorerShell.Verify(s => s.Suspend(), Times.Exactly(2));
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Once);
newDesktop.Verify(d => d.Activate(), Times.Exactly(2));
newDesktop.Verify(d => d.Close(), Times.Once);
originalDesktop.Verify(d => d.Activate(), Times.Once);
}
[TestMethod]
public void Repeat_MustNotReinitializeCreateNewDesktopIfAlreadyActive()
{
var newDesktop = new Mock<IDesktop>();
var originalDesktop = new Mock<IDesktop>();
var success = true;
currentSettings.KioskMode = KioskMode.CreateNewDesktop;
nextSettings.KioskMode = KioskMode.CreateNewDesktop;
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object);
desktopFactory.Setup(f => f.CreateNew(It.IsAny<string>())).Returns(newDesktop.Object);
success &= sut.Perform() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
Assert.IsTrue(success);
desktopFactory.Verify(f => f.GetCurrent(), Times.Once);
desktopFactory.Verify(f => f.CreateNew(It.IsAny<string>()), Times.Once);
newDesktop.Verify(d => d.Activate(), Times.Once);
newDesktop.Verify(d => d.Close(), Times.Never);
processFactory.VerifySet(f => f.StartupDesktop = newDesktop.Object, Times.Once);
explorerShell.Verify(s => s.Suspend(), Times.Once);
explorerShell.Verify(s => s.Resume(), Times.Never);
}
[TestMethod]
public void Repeat_MustNotReinitializeDisableExplorerShellIfAlreadyActive()
{
var success = true;
currentSettings.KioskMode = KioskMode.DisableExplorerShell;
nextSettings.KioskMode = KioskMode.DisableExplorerShell;
success &= sut.Perform() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
success &= sut.Repeat() == OperationResult.Success;
Assert.IsTrue(success);
explorerShell.Verify(s => s.Start(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Once);
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
}
[TestMethod]
public void Revert_MustCorrectlyRevertCreateNewDesktop()
{
var newDesktop = new Mock<IDesktop>();
var originalDesktop = new Mock<IDesktop>();
@ -147,7 +262,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
}
[TestMethod]
public void MustCorrectlyRevertDisableExplorerShell()
public void Revert_MustCorrectlyRevertDisableExplorerShell()
{
var order = 0;
@ -166,125 +281,18 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
Assert.AreEqual(OperationResult.Success, revertResult);
}
[TestMethod]
public void MustCorrectlyStartNewKioskModeWhenRepeating()
{
var newDesktop = new Mock<IDesktop>();
var originalDesktop = new Mock<IDesktop>();
var result = default(OperationResult);
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object);
desktopFactory.Setup(f => f.CreateNew(It.IsAny<string>())).Returns(newDesktop.Object);
nextSettings.KioskMode = KioskMode.CreateNewDesktop;
result = sut.Perform();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Terminate(), Times.Never);
explorerShell.Verify(s => s.Start(), Times.Never);
explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Suspend(), Times.Once);
explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Once);
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
nextSettings.KioskMode = KioskMode.DisableExplorerShell;
result = sut.Repeat();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Terminate(), Times.Once);
explorerShell.Verify(s => s.Start(), Times.Never);
explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Suspend(), Times.Once);
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Once);
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
currentSettings.KioskMode = nextSettings.KioskMode;
nextSettings.KioskMode = KioskMode.CreateNewDesktop;
result = sut.Repeat();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Terminate(), Times.Once);
explorerShell.Verify(s => s.Start(), Times.Never);
explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Suspend(), Times.Exactly(2));
explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Exactly(2));
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
Assert.AreSame(sessionContext.NewDesktop, newDesktop.Object);
Assert.AreSame(sessionContext.OriginalDesktop, originalDesktop.Object);
}
[TestMethod]
public void MustDoNothingWithoutKioskMode()
{
nextSettings.KioskMode = KioskMode.None;
sut.Perform();
sut.Repeat();
sut.Revert();
Assert.AreEqual(OperationResult.Success, sut.Perform());
Assert.AreEqual(OperationResult.Success, sut.Repeat());
Assert.AreEqual(OperationResult.Success, sut.Revert());
desktopFactory.VerifyNoOtherCalls();
explorerShell.VerifyNoOtherCalls();
processFactory.VerifyNoOtherCalls();
}
[TestMethod]
public void MustNotReinitializeCreateNewDesktopWhenRepeating()
{
var newDesktop = new Mock<IDesktop>();
var originalDesktop = new Mock<IDesktop>();
currentSettings.KioskMode = KioskMode.CreateNewDesktop;
nextSettings.KioskMode = KioskMode.CreateNewDesktop;
desktopFactory.Setup(f => f.GetCurrent()).Returns(originalDesktop.Object);
desktopFactory.Setup(f => f.CreateNew(It.IsAny<string>())).Returns(newDesktop.Object);
sut.Perform();
sut.Repeat();
sut.Repeat();
sut.Repeat();
sut.Repeat();
sut.Revert();
desktopFactory.Verify(f => f.GetCurrent(), Times.Once);
desktopFactory.Verify(f => f.CreateNew(It.IsAny<string>()), Times.Once);
newDesktop.Verify(d => d.Activate(), Times.Once);
processFactory.VerifySet(f => f.StartupDesktop = newDesktop.Object, Times.Once);
explorerShell.Verify(s => s.Suspend(), Times.Once);
Assert.AreSame(sessionContext.NewDesktop, newDesktop.Object);
Assert.AreSame(sessionContext.OriginalDesktop, originalDesktop.Object);
}
[TestMethod]
public void MustNotReinitializeDisableExplorerShellWhenRepeating()
{
currentSettings.KioskMode = KioskMode.DisableExplorerShell;
nextSettings.KioskMode = KioskMode.DisableExplorerShell;
sut.Perform();
sut.Repeat();
sut.Repeat();
sut.Repeat();
sut.Repeat();
sut.Revert();
explorerShell.Verify(s => s.Terminate(), Times.Once);
}
}
}

View file

@ -1,187 +0,0 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.WindowsApi;
using SafeExamBrowser.Runtime.Operations;
namespace SafeExamBrowser.Runtime.UnitTests.Operations
{
[TestClass]
public class KioskModeTerminationOperationTests
{
private Mock<IDesktopFactory> desktopFactory;
private Mock<IExplorerShell> explorerShell;
private Mock<ILogger> logger;
private SessionConfiguration nextSession;
private Settings nextSettings;
private Mock<IProcessFactory> processFactory;
private SessionContext sessionContext;
private KioskModeTerminationOperation sut;
private SessionConfiguration currentSession;
private Settings currentSettings;
[TestInitialize]
public void Initialize()
{
currentSession = new SessionConfiguration();
currentSettings = new Settings();
desktopFactory = new Mock<IDesktopFactory>();
explorerShell = new Mock<IExplorerShell>();
logger = new Mock<ILogger>();
nextSession = new SessionConfiguration();
nextSettings = new Settings();
processFactory = new Mock<IProcessFactory>();
sessionContext = new SessionContext();
currentSession.Settings = currentSettings;
nextSession.Settings = nextSettings;
sessionContext.Current = currentSession;
sessionContext.Next = nextSession;
sut = new KioskModeTerminationOperation(desktopFactory.Object, explorerShell.Object, logger.Object, processFactory.Object, sessionContext);
}
[TestMethod]
public void MustDoNothingOnPerform()
{
var result = sut.Perform();
desktopFactory.VerifyNoOtherCalls();
explorerShell.VerifyNoOtherCalls();
logger.VerifyNoOtherCalls();
processFactory.VerifyNoOtherCalls();
Assert.AreEqual(OperationResult.Success, result);
}
[TestMethod]
public void MustCorrectlyTerminateOldKioskModeWhenRepeating()
{
var newDesktop = new Mock<IDesktop>();
var originalDesktop = new Mock<IDesktop>();
var result = default(OperationResult);
sessionContext.NewDesktop = newDesktop.Object;
sessionContext.OriginalDesktop = originalDesktop.Object;
sessionContext.ActiveMode = KioskMode.DisableExplorerShell;
nextSettings.KioskMode = KioskMode.CreateNewDesktop;
result = sut.Repeat();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Start(), Times.Once);
explorerShell.Verify(s => s.Suspend(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Never);
explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Once);
newDesktop.Verify(d => d.Activate(), Times.Never);
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
sessionContext.ActiveMode = nextSettings.KioskMode;
nextSettings.KioskMode = KioskMode.DisableExplorerShell;
result = sut.Repeat();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Resume(), Times.Once);
explorerShell.Verify(s => s.Start(), Times.Once);
explorerShell.Verify(s => s.Suspend(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Never);
explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Once);
newDesktop.Verify(d => d.Activate(), Times.Never);
newDesktop.Verify(d => d.Close(), Times.Once);
originalDesktop.Verify(d => d.Activate(), Times.Once);
sessionContext.ActiveMode = nextSettings.KioskMode;
nextSettings.KioskMode = KioskMode.CreateNewDesktop;
result = sut.Repeat();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Resume(), Times.Once);
explorerShell.Verify(s => s.Start(), Times.Exactly(2));
explorerShell.Verify(s => s.Suspend(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Never);
explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Exactly(2));
newDesktop.Verify(d => d.Activate(), Times.Never);
newDesktop.Verify(d => d.Close(), Times.Once);
originalDesktop.Verify(d => d.Activate(), Times.Once);
}
[TestMethod]
public void MustNotTerminateKioskModeIfSameInNextSesssion()
{
var newDesktop = new Mock<IDesktop>();
var originalDesktop = new Mock<IDesktop>();
var result = default(OperationResult);
sessionContext.NewDesktop = newDesktop.Object;
sessionContext.OriginalDesktop = originalDesktop.Object;
sessionContext.ActiveMode = KioskMode.DisableExplorerShell;
nextSettings.KioskMode = KioskMode.DisableExplorerShell;
result = sut.Repeat();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Start(), Times.Never);
explorerShell.Verify(s => s.Suspend(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Never);
explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Never);
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
sessionContext.ActiveMode = KioskMode.CreateNewDesktop;
nextSettings.KioskMode = KioskMode.CreateNewDesktop;
result = sut.Repeat();
Assert.AreEqual(OperationResult.Success, result);
explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Start(), Times.Never);
explorerShell.Verify(s => s.Suspend(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Never);
explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Never);
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
}
[TestMethod]
public void MustDoNothingOnRevert()
{
var result = sut.Revert();
desktopFactory.VerifyNoOtherCalls();
explorerShell.VerifyNoOtherCalls();
logger.VerifyNoOtherCalls();
processFactory.VerifyNoOtherCalls();
Assert.AreEqual(OperationResult.Success, result);
}
}
}

View file

@ -85,7 +85,6 @@
<Compile Include="Operations\ClientTerminationOperationTests.cs" />
<Compile Include="Operations\ConfigurationOperationTests.cs" />
<Compile Include="Operations\KioskModeOperationTests.cs" />
<Compile Include="Operations\KioskModeTerminationOperationTests.cs" />
<Compile Include="Operations\ServiceOperationTests.cs" />
<Compile Include="Operations\ClientOperationTests.cs" />
<Compile Include="Operations\SessionActivationOperationTests.cs" />

View file

@ -79,9 +79,8 @@ namespace SafeExamBrowser.Runtime
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost, sessionContext));
sessionOperations.Enqueue(new ConfigurationOperation(args, configuration, new HashAlgorithm(), logger, sessionContext));
sessionOperations.Enqueue(new ClientTerminationOperation(logger, processFactory, proxyFactory, runtimeHost, sessionContext, THIRTY_SECONDS));
sessionOperations.Enqueue(new KioskModeTerminationOperation(desktopFactory, explorerShell, logger, processFactory, sessionContext));
sessionOperations.Enqueue(new ServiceOperation(logger, runtimeHost, serviceProxy, sessionContext, THIRTY_SECONDS));
sessionOperations.Enqueue(new ClientTerminationOperation(logger, processFactory, proxyFactory, runtimeHost, sessionContext, THIRTY_SECONDS));
sessionOperations.Enqueue(new KioskModeOperation(desktopFactory, explorerShell, logger, processFactory, sessionContext));
sessionOperations.Enqueue(new ClientOperation(logger, processFactory, proxyFactory, runtimeHost, sessionContext, THIRTY_SECONDS));
sessionOperations.Enqueue(new SessionActivationOperation(logger, sessionContext));

View file

@ -17,30 +17,14 @@ namespace SafeExamBrowser.Runtime.Operations
{
internal class KioskModeOperation : SessionOperation
{
private IDesktop newDesktop;
private IDesktop originalDesktop;
private IDesktopFactory desktopFactory;
private IExplorerShell explorerShell;
private KioskMode? activeMode;
private ILogger logger;
private IProcessFactory processFactory;
protected ILogger logger;
private IDesktop NewDesktop
{
get { return Context.NewDesktop; }
set { Context.NewDesktop = value; }
}
private IDesktop OriginalDesktop
{
get { return Context.OriginalDesktop; }
set { Context.OriginalDesktop = value; }
}
protected KioskMode? ActiveMode
{
get { return Context.ActiveMode; }
set { Context.ActiveMode = value; }
}
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
public override event StatusChangedEventHandler StatusChanged;
@ -62,7 +46,7 @@ namespace SafeExamBrowser.Runtime.Operations
logger.Info($"Initializing kiosk mode '{Context.Next.Settings.KioskMode}'...");
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeKioskMode);
ActiveMode = Context.Next.Settings.KioskMode;
activeMode = Context.Next.Settings.KioskMode;
switch (Context.Next.Settings.KioskMode)
{
@ -80,23 +64,31 @@ namespace SafeExamBrowser.Runtime.Operations
public override OperationResult Repeat()
{
var newMode = Context.Next.Settings.KioskMode;
var result = OperationResult.Success;
if (ActiveMode == newMode)
if (activeMode == newMode)
{
logger.Info($"New kiosk mode '{newMode}' is already active, skipping initialization...");
logger.Info($"New kiosk mode '{newMode}' is the same as the currently active mode, skipping re-initialization...");
}
else
{
result = Revert();
return OperationResult.Success;
if (result == OperationResult.Success)
{
result = Perform();
}
}
return Perform();
return result;
}
public override OperationResult Revert()
{
logger.Info($"Reverting kiosk mode '{ActiveMode}'...");
logger.Info($"Reverting kiosk mode '{activeMode}'...");
StatusChanged?.Invoke(TextKey.OperationStatus_RevertKioskMode);
switch (ActiveMode)
switch (activeMode)
{
case KioskMode.CreateNewDesktop:
CloseNewDesktop();
@ -111,14 +103,14 @@ namespace SafeExamBrowser.Runtime.Operations
private void CreateNewDesktop()
{
OriginalDesktop = desktopFactory.GetCurrent();
logger.Info($"Current desktop is {OriginalDesktop}.");
originalDesktop = desktopFactory.GetCurrent();
logger.Info($"Current desktop is {originalDesktop}.");
NewDesktop = desktopFactory.CreateNew(nameof(SafeExamBrowser));
logger.Info($"Created new desktop {NewDesktop}.");
newDesktop = desktopFactory.CreateNew(nameof(SafeExamBrowser));
logger.Info($"Created new desktop {newDesktop}.");
NewDesktop.Activate();
processFactory.StartupDesktop = NewDesktop;
newDesktop.Activate();
processFactory.StartupDesktop = newDesktop;
logger.Info("Successfully activated new desktop.");
explorerShell.Suspend();
@ -126,21 +118,21 @@ namespace SafeExamBrowser.Runtime.Operations
private void CloseNewDesktop()
{
if (OriginalDesktop != null)
if (originalDesktop != null)
{
OriginalDesktop.Activate();
processFactory.StartupDesktop = OriginalDesktop;
logger.Info($"Switched back to original desktop {OriginalDesktop}.");
originalDesktop.Activate();
processFactory.StartupDesktop = originalDesktop;
logger.Info($"Switched back to original desktop {originalDesktop}.");
}
else
{
logger.Warn($"No original desktop found to activate!");
}
if (NewDesktop != null)
if (newDesktop != null)
{
NewDesktop.Close();
logger.Info($"Closed new desktop {NewDesktop}.");
newDesktop.Close();
logger.Info($"Closed new desktop {newDesktop}.");
}
else
{

View file

@ -1,50 +0,0 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.WindowsApi;
namespace SafeExamBrowser.Runtime.Operations
{
internal class KioskModeTerminationOperation : KioskModeOperation, IRepeatableOperation
{
public KioskModeTerminationOperation(
IDesktopFactory desktopFactory,
IExplorerShell explorerShell,
ILogger logger,
IProcessFactory processFactory,
SessionContext sessionContext) : base(desktopFactory, explorerShell, logger, processFactory, sessionContext)
{
}
public override OperationResult Perform()
{
return OperationResult.Success;
}
public override OperationResult Repeat()
{
var newMode = Context.Next.Settings.KioskMode;
if (ActiveMode == newMode)
{
logger.Info($"New kiosk mode '{newMode}' is the same as the currently active, skipping termination...");
return OperationResult.Success;
}
return base.Revert();
}
public override OperationResult Revert()
{
return OperationResult.Success;
}
}
}

View file

@ -99,7 +99,6 @@
<Compile Include="Operations\Events\PasswordRequiredEventArgs.cs" />
<Compile Include="Operations\Events\UnexpectedErrorMessageArgs.cs" />
<Compile Include="Operations\KioskModeOperation.cs" />
<Compile Include="Operations\KioskModeTerminationOperation.cs" />
<Compile Include="Operations\ServiceOperation.cs" />
<Compile Include="Operations\SessionActivationOperation.cs" />
<Compile Include="Operations\SessionOperation.cs" />

View file

@ -8,7 +8,6 @@
using SafeExamBrowser.Contracts.Communication.Proxies;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.WindowsApi;
namespace SafeExamBrowser.Runtime
@ -18,11 +17,6 @@ namespace SafeExamBrowser.Runtime
/// </summary>
internal class SessionContext
{
/// <summary>
/// The currently active <see cref="KioskMode"/>.
/// </summary>
internal KioskMode? ActiveMode { get; set; }
/// <summary>
/// The currently running client process.
/// </summary>
@ -38,21 +32,11 @@ namespace SafeExamBrowser.Runtime
/// </summary>
internal SessionConfiguration Current { get; set; }
/// <summary>
/// The new desktop, if <see cref="KioskMode.CreateNewDesktop"/> is currently active.
/// </summary>
internal IDesktop NewDesktop { get; set; }
/// <summary>
/// The configuration of the next session to be activated.
/// </summary>
internal SessionConfiguration Next { get; set; }
/// <summary>
/// The original desktop, if <see cref="KioskMode.CreateNewDesktop"/> is currently active.
/// </summary>
internal IDesktop OriginalDesktop { get; set; }
/// <summary>
/// The path of the configuration file to be used for reconfiguration.
/// </summary>