SEBPatch/SafeExamBrowser.Client/ClientController.cs

142 lines
3.6 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.Client.Responsibilities;
using SafeExamBrowser.Communication.Contracts.Proxies;
using SafeExamBrowser.Core.Contracts.OperationModel;
using SafeExamBrowser.Core.Contracts.ResponsibilityModel;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.UserInterface.Contracts.Windows;
namespace SafeExamBrowser.Client
{
internal class ClientController
{
private readonly ClientContext context;
private readonly ILogger logger;
private readonly IOperationSequence operations;
private readonly IResponsibilityCollection<ClientTask> responsibilities;
private readonly IRuntimeProxy runtime;
private readonly ISplashScreen splashScreen;
internal ClientController(
ClientContext context,
ILogger logger,
IOperationSequence operations,
IResponsibilityCollection<ClientTask> responsibilities,
IRuntimeProxy runtime,
ISplashScreen splashScreen)
{
this.context = context;
this.logger = logger;
this.operations = operations;
this.responsibilities = responsibilities;
this.runtime = runtime;
this.splashScreen = splashScreen;
}
internal bool TryStart()
{
logger.Info("Initiating startup procedure...");
splashScreen.Show();
splashScreen.BringToForeground();
var initialized = false;
var result = operations.TryPerform();
if (result == OperationResult.Success)
{
DelegateStartupResponsibilities();
initialized = TryInformRuntime();
}
else
{
logger.Info($"Application startup {(result == OperationResult.Aborted ? "aborted" : "failed")}!");
logger.Log(string.Empty);
}
if (initialized)
{
logger.Info("Application successfully initialized.");
logger.Log(string.Empty);
DelegateClientReadyResponsibilities();
}
splashScreen.Hide();
return initialized;
}
internal void Terminate()
{
logger.Log(string.Empty);
logger.Info("Initiating shutdown procedure...");
splashScreen.Show();
splashScreen.BringToForeground();
DelegateShutdownResponsibilities();
var success = operations.TryRevert() == OperationResult.Success;
if (success)
{
logger.Info("Application successfully finalized.");
logger.Log(string.Empty);
}
else
{
logger.Info("Application shutdown failed!");
logger.Log(string.Empty);
}
splashScreen.Close();
}
internal void UpdateAppConfig()
{
splashScreen.AppConfig = context.AppConfig;
}
private void DelegateStartupResponsibilities()
{
responsibilities.Delegate(ClientTask.RegisterEvents);
responsibilities.Delegate(ClientTask.ShowShell);
responsibilities.Delegate(ClientTask.AutoStartApplications);
//responsibilities.Delegate(ClientTask.ScheduleIntegrityVerification);
//responsibilities.Delegate(ClientTask.StartMonitoring);
}
private void DelegateClientReadyResponsibilities()
{
//responsibilities.Delegate(ClientTask.VerifySessionIntegrity);
}
private void DelegateShutdownResponsibilities()
{
responsibilities.Delegate(ClientTask.CloseShell);
responsibilities.Delegate(ClientTask.DeregisterEvents);
//responsibilities.Delegate(ClientTask.UpdateSessionIntegrity);
}
private bool TryInformRuntime()
{
var communication = runtime.InformClientReady();
if (!communication.Success)
{
logger.Error("Failed to inform runtime that client is ready!");
}
return communication.Success;
}
}
}