SEBWIN-360: Fixed concurrency issue when reconfiguring and improved client performance by having only one splash screen.

This commit is contained in:
dbuechel 2020-02-14 14:43:08 +01:00
parent d5210e85b7
commit 19bf6df812
3 changed files with 33 additions and 37 deletions

View file

@ -58,6 +58,7 @@ namespace SafeExamBrowser.Client.UnitTests
private Guid sessionId; private Guid sessionId;
private AppSettings settings; private AppSettings settings;
private Mock<Action> shutdown; private Mock<Action> shutdown;
private Mock<ISplashScreen> splashScreen;
private Mock<ITaskbar> taskbar; private Mock<ITaskbar> taskbar;
private Mock<IText> text; private Mock<IText> text;
private Mock<IUserInterfaceFactory> uiFactory; private Mock<IUserInterfaceFactory> uiFactory;
@ -84,6 +85,7 @@ namespace SafeExamBrowser.Client.UnitTests
sessionId = Guid.NewGuid(); sessionId = Guid.NewGuid();
settings = new AppSettings(); settings = new AppSettings();
shutdown = new Mock<Action>(); shutdown = new Mock<Action>();
splashScreen = new Mock<ISplashScreen>();
taskbar = new Mock<ITaskbar>(); taskbar = new Mock<ITaskbar>();
text = new Mock<IText>(); text = new Mock<IText>();
uiFactory = new Mock<IUserInterfaceFactory>(); uiFactory = new Mock<IUserInterfaceFactory>();
@ -105,6 +107,7 @@ namespace SafeExamBrowser.Client.UnitTests
operationSequence.Object, operationSequence.Object,
runtimeProxy.Object, runtimeProxy.Object,
shutdown.Object, shutdown.Object,
splashScreen.Object,
taskbar.Object, taskbar.Object,
text.Object, text.Object,
uiFactory.Object); uiFactory.Object);
@ -300,14 +303,10 @@ namespace SafeExamBrowser.Client.UnitTests
[TestMethod] [TestMethod]
public void Communication_MustCorrectlyHandleAbortedReconfiguration() public void Communication_MustCorrectlyHandleAbortedReconfiguration()
{ {
var splashScreen = new Mock<ISplashScreen>();
uiFactory.Setup(f => f.CreateSplashScreen(It.IsAny<AppConfig>())).Returns(splashScreen.Object);
sut.TryStart(); sut.TryStart();
clientHost.Raise(c => c.ReconfigurationAborted += null); clientHost.Raise(c => c.ReconfigurationAborted += null);
splashScreen.Verify(s => s.Close(), Times.AtLeastOnce); splashScreen.Verify(s => s.Hide(), Times.AtLeastOnce);
} }
[TestMethod] [TestMethod]
@ -498,9 +497,6 @@ namespace SafeExamBrowser.Client.UnitTests
Progress = true, Progress = true,
Regress = true Regress = true
}; };
var splashScreen = new Mock<ISplashScreen>();
uiFactory.Setup(u => u.CreateSplashScreen(It.IsAny<AppConfig>())).Returns(splashScreen.Object);
sut.TryStart(); sut.TryStart();
operationSequence.Raise(o => o.ProgressChanged += null, args); operationSequence.Raise(o => o.ProgressChanged += null, args);
@ -516,9 +512,6 @@ namespace SafeExamBrowser.Client.UnitTests
public void Operations_MustUpdateStatus() public void Operations_MustUpdateStatus()
{ {
var key = TextKey.OperationStatus_EmptyClipboard; var key = TextKey.OperationStatus_EmptyClipboard;
var splashScreen = new Mock<ISplashScreen>();
uiFactory.Setup(u => u.CreateSplashScreen(It.IsAny<AppConfig>())).Returns(splashScreen.Object);
sut.TryStart(); sut.TryStart();
operationSequence.Raise(o => o.StatusChanged += null, key); operationSequence.Raise(o => o.StatusChanged += null, key);
@ -835,10 +828,6 @@ namespace SafeExamBrowser.Client.UnitTests
[TestMethod] [TestMethod]
public void Startup_MustUpdateAppConfigForSplashScreen() public void Startup_MustUpdateAppConfigForSplashScreen()
{ {
var splashScreen = new Mock<ISplashScreen>();
uiFactory.Setup(u => u.CreateSplashScreen(It.IsAny<AppConfig>())).Returns(splashScreen.Object);
sut.TryStart(); sut.TryStart();
sut.UpdateAppConfig(); sut.UpdateAppConfig();

View file

@ -73,6 +73,7 @@ namespace SafeExamBrowser.Client
IOperationSequence operations, IOperationSequence operations,
IRuntimeProxy runtime, IRuntimeProxy runtime,
Action shutdown, Action shutdown,
ISplashScreen splashScreen,
ITaskbar taskbar, ITaskbar taskbar,
IText text, IText text,
IUserInterfaceFactory uiFactory) IUserInterfaceFactory uiFactory)
@ -89,6 +90,7 @@ namespace SafeExamBrowser.Client
this.operations = operations; this.operations = operations;
this.runtime = runtime; this.runtime = runtime;
this.shutdown = shutdown; this.shutdown = shutdown;
this.splashScreen = splashScreen;
this.taskbar = taskbar; this.taskbar = taskbar;
this.text = text; this.text = text;
this.uiFactory = uiFactory; this.uiFactory = uiFactory;
@ -98,11 +100,13 @@ namespace SafeExamBrowser.Client
{ {
logger.Info("Initiating startup procedure..."); logger.Info("Initiating startup procedure...");
splashScreen = uiFactory.CreateSplashScreen();
operations.ActionRequired += Operations_ActionRequired; operations.ActionRequired += Operations_ActionRequired;
operations.ProgressChanged += Operations_ProgressChanged; operations.ProgressChanged += Operations_ProgressChanged;
operations.StatusChanged += Operations_StatusChanged; operations.StatusChanged += Operations_StatusChanged;
splashScreen.Show();
splashScreen.BringToForeground();
var success = operations.TryPerform() == OperationResult.Success; var success = operations.TryPerform() == OperationResult.Success;
if (success) if (success)
@ -130,7 +134,7 @@ namespace SafeExamBrowser.Client
logger.Log(string.Empty); logger.Log(string.Empty);
} }
splashScreen.Close(); splashScreen.Hide();
return success; return success;
} }
@ -140,7 +144,8 @@ namespace SafeExamBrowser.Client
logger.Log(string.Empty); logger.Log(string.Empty);
logger.Info("Initiating shutdown procedure..."); logger.Info("Initiating shutdown procedure...");
splashScreen = uiFactory.CreateSplashScreen(context.AppConfig); splashScreen.Show();
splashScreen.BringToForeground();
CloseShell(); CloseShell();
DeregisterEvents(); DeregisterEvents();
@ -162,12 +167,9 @@ namespace SafeExamBrowser.Client
} }
public void UpdateAppConfig() public void UpdateAppConfig()
{
if (splashScreen != null)
{ {
splashScreen.AppConfig = context.AppConfig; splashScreen.AppConfig = context.AppConfig;
} }
}
private void RegisterEvents() private void RegisterEvents()
{ {
@ -340,6 +342,12 @@ namespace SafeExamBrowser.Client
args.AllowDownload = true; args.AllowDownload = true;
args.Callback = Browser_ConfigurationDownloadFinished; args.Callback = Browser_ConfigurationDownloadFinished;
args.DownloadPath = Path.Combine(context.AppConfig.TemporaryDirectory, fileName); args.DownloadPath = Path.Combine(context.AppConfig.TemporaryDirectory, fileName);
splashScreen.Show();
splashScreen.BringToForeground();
splashScreen.SetIndeterminate();
splashScreen.UpdateStatus(TextKey.OperationStatus_InitializeSession, true);
logger.Info($"Allowed download request for configuration file '{fileName}'."); logger.Info($"Allowed download request for configuration file '{fileName}'.");
} }
else else
@ -364,22 +372,19 @@ namespace SafeExamBrowser.Client
if (communication.Success) if (communication.Success)
{ {
logger.Info($"Sent reconfiguration request for '{filePath}' to the runtime."); logger.Info($"Sent reconfiguration request for '{filePath}' to the runtime.");
splashScreen = uiFactory.CreateSplashScreen(context.AppConfig);
splashScreen.SetIndeterminate();
splashScreen.UpdateStatus(TextKey.OperationStatus_InitializeSession, true);
splashScreen.Show();
} }
else else
{ {
logger.Error($"Failed to communicate reconfiguration request for '{filePath}'!"); logger.Error($"Failed to communicate reconfiguration request for '{filePath}'!");
messageBox.Show(TextKey.MessageBox_ReconfigurationError, TextKey.MessageBox_ReconfigurationErrorTitle, icon: MessageBoxIcon.Error); messageBox.Show(TextKey.MessageBox_ReconfigurationError, TextKey.MessageBox_ReconfigurationErrorTitle, icon: MessageBoxIcon.Error, parent: splashScreen);
splashScreen.Hide();
} }
} }
else else
{ {
logger.Error($"Failed to download configuration file '{filePath}'!"); logger.Error($"Failed to download configuration file '{filePath}'!");
messageBox.Show(TextKey.MessageBox_ConfigurationDownloadError, TextKey.MessageBox_ConfigurationDownloadErrorTitle, icon: MessageBoxIcon.Error); messageBox.Show(TextKey.MessageBox_ConfigurationDownloadError, TextKey.MessageBox_ConfigurationDownloadErrorTitle, icon: MessageBoxIcon.Error, parent: splashScreen);
splashScreen.Hide();
} }
} }
@ -428,14 +433,14 @@ namespace SafeExamBrowser.Client
private void ClientHost_ReconfigurationAborted() private void ClientHost_ReconfigurationAborted()
{ {
logger.Info("The reconfiguration was aborted by the runtime."); logger.Info("The reconfiguration was aborted by the runtime.");
splashScreen?.Close(); splashScreen.Hide();
} }
private void ClientHost_ReconfigurationDenied(ReconfigurationEventArgs args) private void ClientHost_ReconfigurationDenied(ReconfigurationEventArgs args)
{ {
logger.Info($"The reconfiguration request for '{args.ConfigurationPath}' was denied by the runtime!"); logger.Info($"The reconfiguration request for '{args.ConfigurationPath}' was denied by the runtime!");
messageBox.Show(TextKey.MessageBox_ReconfigurationDenied, TextKey.MessageBox_ReconfigurationDeniedTitle, parent: splashScreen); messageBox.Show(TextKey.MessageBox_ReconfigurationDenied, TextKey.MessageBox_ReconfigurationDeniedTitle, parent: splashScreen);
splashScreen?.Close(); splashScreen.Hide();
} }
private void ClientHost_Shutdown() private void ClientHost_Shutdown()
@ -476,33 +481,33 @@ namespace SafeExamBrowser.Client
{ {
if (args.CurrentValue.HasValue) if (args.CurrentValue.HasValue)
{ {
splashScreen?.SetValue(args.CurrentValue.Value); splashScreen.SetValue(args.CurrentValue.Value);
} }
if (args.IsIndeterminate == true) if (args.IsIndeterminate == true)
{ {
splashScreen?.SetIndeterminate(); splashScreen.SetIndeterminate();
} }
if (args.MaxValue.HasValue) if (args.MaxValue.HasValue)
{ {
splashScreen?.SetMaxValue(args.MaxValue.Value); splashScreen.SetMaxValue(args.MaxValue.Value);
} }
if (args.Progress == true) if (args.Progress == true)
{ {
splashScreen?.Progress(); splashScreen.Progress();
} }
if (args.Regress == true) if (args.Regress == true)
{ {
splashScreen?.Regress(); splashScreen.Regress();
} }
} }
private void Operations_StatusChanged(TextKey status) private void Operations_StatusChanged(TextKey status)
{ {
splashScreen?.UpdateStatus(status, true); splashScreen.UpdateStatus(status, true);
} }
private void Runtime_ConnectionLost() private void Runtime_ConnectionLost()

View file

@ -105,6 +105,7 @@ namespace SafeExamBrowser.Client
var explorerShell = new ExplorerShell(ModuleLogger(nameof(ExplorerShell)), nativeMethods); var explorerShell = new ExplorerShell(ModuleLogger(nameof(ExplorerShell)), nativeMethods);
var fileSystemDialog = BuildFileSystemDialog(); var fileSystemDialog = BuildFileSystemDialog();
var hashAlgorithm = new HashAlgorithm(); var hashAlgorithm = new HashAlgorithm();
var splashScreen = uiFactory.CreateSplashScreen();
var operations = new Queue<IOperation>(); var operations = new Queue<IOperation>();
@ -137,6 +138,7 @@ namespace SafeExamBrowser.Client
sequence, sequence,
runtimeProxy, runtimeProxy,
shutdown, shutdown,
splashScreen,
taskbar, taskbar,
text, text,
uiFactory); uiFactory);