119 lines
3.4 KiB
C#
119 lines
3.4 KiB
C#
/*
|
|
* Copyright (c) 2025 ETH Zürich, IT Services
|
|
*
|
|
* 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.Core.Contracts.OperationModel;
|
|
using SafeExamBrowser.Core.Contracts.ResponsibilityModel;
|
|
using SafeExamBrowser.Logging.Contracts;
|
|
using SafeExamBrowser.Runtime.Responsibilities;
|
|
using SafeExamBrowser.UserInterface.Contracts.Windows;
|
|
using System.Deployment.Internal;
|
|
|
|
namespace SafeExamBrowser.Runtime
|
|
{
|
|
internal class RuntimeController
|
|
{
|
|
private readonly ILogger logger;
|
|
private readonly IOperationSequence bootstrapSequence;
|
|
private readonly IResponsibilityCollection<RuntimeTask> responsibilities;
|
|
private readonly RuntimeContext runtimeContext;
|
|
private readonly IRuntimeWindow runtimeWindow;
|
|
private readonly ISplashScreen splashScreen;
|
|
|
|
private bool SessionIsRunning => runtimeContext.Current != default;
|
|
|
|
internal RuntimeController(
|
|
ILogger logger,
|
|
IOperationSequence bootstrapSequence,
|
|
IResponsibilityCollection<RuntimeTask> responsibilities,
|
|
RuntimeContext runtimeContext,
|
|
IRuntimeWindow runtimeWindow,
|
|
ISplashScreen splashScreen)
|
|
{
|
|
this.bootstrapSequence = bootstrapSequence;
|
|
this.responsibilities = responsibilities;
|
|
this.logger = logger;
|
|
this.runtimeWindow = runtimeWindow;
|
|
this.runtimeContext = runtimeContext;
|
|
this.splashScreen = splashScreen;
|
|
}
|
|
|
|
internal bool TryStart()
|
|
{
|
|
logger.Info("Initiating startup procedure...");
|
|
// We need to show the runtime window here already, this way implicitly setting it as the runtime application's main window.
|
|
// Otherwise, the splash screen is considered as the main window and thus the operating system and/or WPF does not correctly
|
|
// activate the runtime window once bootstrapping has finished, which in turn leads to undesired user interface behavior.
|
|
runtimeWindow.Show();
|
|
runtimeWindow.BringToForeground();
|
|
runtimeWindow.SetIndeterminate();
|
|
|
|
splashScreen.Show();
|
|
splashScreen.BringToForeground();
|
|
|
|
var initialized = bootstrapSequence.TryPerform() == OperationResult.Success;
|
|
|
|
if (initialized)
|
|
{
|
|
responsibilities.Delegate(RuntimeTask.RegisterEvents);
|
|
splashScreen.Hide();
|
|
|
|
logger.Info("Application successfully initialized.");
|
|
logger.Log(string.Empty);
|
|
logger.Subscribe(runtimeWindow);
|
|
|
|
responsibilities.Delegate(RuntimeTask.StartSession);
|
|
}
|
|
else
|
|
{
|
|
logger.Info("Application startup aborted!");
|
|
logger.Log(string.Empty);
|
|
|
|
responsibilities.Delegate(RuntimeTask.ShowStartupError);
|
|
}
|
|
|
|
return initialized && SessionIsRunning;
|
|
}
|
|
|
|
internal void Terminate()
|
|
{
|
|
responsibilities.Delegate(RuntimeTask.DeregisterEvents);
|
|
|
|
if (SessionIsRunning)
|
|
{
|
|
responsibilities.Delegate(RuntimeTask.StopSession);
|
|
}
|
|
|
|
logger.Unsubscribe(runtimeWindow);
|
|
runtimeWindow.Close();
|
|
|
|
splashScreen.Show();
|
|
splashScreen.BringToForeground();
|
|
|
|
logger.Log(string.Empty);
|
|
logger.Info("Initiating shutdown procedure...");
|
|
|
|
var success = bootstrapSequence.TryRevert() == OperationResult.Success;
|
|
|
|
if (success)
|
|
{
|
|
logger.Info("Application successfully finalized.");
|
|
logger.Log(string.Empty);
|
|
}
|
|
else
|
|
{
|
|
logger.Info("Shutdown procedure failed!");
|
|
logger.Log(string.Empty);
|
|
|
|
responsibilities.Delegate(RuntimeTask.ShowShutdownError);
|
|
}
|
|
|
|
splashScreen.Close();
|
|
}
|
|
}
|
|
}
|