Restore SEBPatch
This commit is contained in:
204
SafeExamBrowser.Client/Operations/ApplicationOperation.cs
Normal file
204
SafeExamBrowser.Client/Operations/ApplicationOperation.cs
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Client.Operations.Events;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Applications;
|
||||
using SafeExamBrowser.Settings.Applications;
|
||||
using SafeExamBrowser.Settings.Security;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class ApplicationOperation : ClientOperation
|
||||
{
|
||||
private IApplicationFactory factory;
|
||||
private ILogger logger;
|
||||
private IApplicationMonitor monitor;
|
||||
private IText text;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired;
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public ApplicationOperation(
|
||||
ClientContext context,
|
||||
IApplicationFactory factory,
|
||||
IApplicationMonitor monitor,
|
||||
ILogger logger,
|
||||
IText text) : base(context)
|
||||
{
|
||||
this.factory = factory;
|
||||
this.monitor = monitor;
|
||||
this.logger = logger;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
logger.Info("Initializing applications...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeApplications);
|
||||
|
||||
var result = InitializeApplications();
|
||||
|
||||
if (result == OperationResult.Success)
|
||||
{
|
||||
StartMonitor();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
logger.Info("Finalizing applications...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_FinalizeApplications);
|
||||
|
||||
FinalizeApplications();
|
||||
StopMonitor();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
private OperationResult InitializeApplications()
|
||||
{
|
||||
var initialization = monitor.Initialize(Context.Settings.Applications);
|
||||
var result = OperationResult.Success;
|
||||
|
||||
if (initialization.FailedAutoTerminations.Any())
|
||||
{
|
||||
result = HandleAutoTerminationFailure(initialization.FailedAutoTerminations);
|
||||
}
|
||||
else if (initialization.RunningApplications.Any())
|
||||
{
|
||||
result = TryTerminate(initialization.RunningApplications);
|
||||
}
|
||||
|
||||
if (result == OperationResult.Success)
|
||||
{
|
||||
foreach (var application in Context.Settings.Applications.Whitelist)
|
||||
{
|
||||
Initialize(application);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void Initialize(WhitelistApplication settings)
|
||||
{
|
||||
var result = factory.TryCreate(settings, out var application);
|
||||
|
||||
while (result == FactoryResult.NotFound && settings.AllowCustomPath)
|
||||
{
|
||||
var args = new ApplicationNotFoundEventArgs(settings.DisplayName, settings.ExecutableName);
|
||||
|
||||
ActionRequired?.Invoke(args);
|
||||
|
||||
if (args.Success)
|
||||
{
|
||||
settings.ExecutablePath = args.CustomPath;
|
||||
result = factory.TryCreate(settings, out application);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == FactoryResult.Success)
|
||||
{
|
||||
Context.Applications.Add(application);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error($"Failed to initialize application '{settings.DisplayName}' ({settings.ExecutableName}). Reason: {result}.");
|
||||
ActionRequired?.Invoke(new ApplicationInitializationFailedEventArgs(settings.DisplayName, settings.ExecutableName, result));
|
||||
}
|
||||
}
|
||||
|
||||
private void FinalizeApplications()
|
||||
{
|
||||
foreach (var application in Context.Applications)
|
||||
{
|
||||
application.Terminate();
|
||||
}
|
||||
}
|
||||
|
||||
private OperationResult HandleAutoTerminationFailure(IList<RunningApplication> applications)
|
||||
{
|
||||
logger.Error($"{applications.Count} application(s) could not be automatically terminated: {string.Join(", ", applications.Select(a => a.Name))}");
|
||||
ActionRequired?.Invoke(new ApplicationTerminationFailedEventArgs(applications));
|
||||
|
||||
return OperationResult.Failed;
|
||||
}
|
||||
|
||||
private void StartMonitor()
|
||||
{
|
||||
if (Context.Settings.Security.KioskMode != KioskMode.None)
|
||||
{
|
||||
monitor.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void StopMonitor()
|
||||
{
|
||||
if (Context.Settings.Security.KioskMode != KioskMode.None)
|
||||
{
|
||||
monitor.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private OperationResult TryTerminate(IEnumerable<RunningApplication> runningApplications)
|
||||
{
|
||||
var args = new ApplicationTerminationEventArgs(runningApplications);
|
||||
var failed = new List<RunningApplication>();
|
||||
var result = OperationResult.Success;
|
||||
|
||||
logger.Info($"The following applications need to be terminated: {string.Join(", ", runningApplications.Select(a => a.Name))}.");
|
||||
ActionRequired?.Invoke(args);
|
||||
|
||||
if (args.TerminateProcesses)
|
||||
{
|
||||
logger.Info($"The user chose to automatically terminate all running applications.");
|
||||
|
||||
foreach (var application in runningApplications)
|
||||
{
|
||||
var success = monitor.TryTerminate(application);
|
||||
|
||||
if (success)
|
||||
{
|
||||
logger.Info($"Successfully terminated application '{application.Name}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
result = OperationResult.Failed;
|
||||
failed.Add(application);
|
||||
logger.Error($"Failed to automatically terminate application '{application.Name}'!");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info("The user chose not to automatically terminate all running applications. Aborting...");
|
||||
result = OperationResult.Aborted;
|
||||
}
|
||||
|
||||
if (failed.Any())
|
||||
{
|
||||
ActionRequired?.Invoke(new ApplicationTerminationFailedEventArgs(failed));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
90
SafeExamBrowser.Client/Operations/BrowserOperation.cs
Normal file
90
SafeExamBrowser.Client/Operations/BrowserOperation.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class BrowserOperation : ClientOperation
|
||||
{
|
||||
private readonly IActionCenter actionCenter;
|
||||
private readonly ILogger logger;
|
||||
private readonly ITaskbar taskbar;
|
||||
private readonly ITaskview taskview;
|
||||
private readonly IUserInterfaceFactory uiFactory;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public BrowserOperation(
|
||||
IActionCenter actionCenter,
|
||||
ClientContext context,
|
||||
ILogger logger,
|
||||
ITaskbar taskbar,
|
||||
ITaskview taskview,
|
||||
IUserInterfaceFactory uiFactory) : base(context)
|
||||
{
|
||||
this.actionCenter = actionCenter;
|
||||
this.logger = logger;
|
||||
this.taskbar = taskbar;
|
||||
this.taskview = taskview;
|
||||
this.uiFactory = uiFactory;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
logger.Info("Initializing browser...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeBrowser);
|
||||
|
||||
if (Context.Settings.Browser.EnableBrowser)
|
||||
{
|
||||
Context.Browser.Initialize();
|
||||
|
||||
if (Context.Settings.UserInterface.ActionCenter.EnableActionCenter)
|
||||
{
|
||||
actionCenter.AddApplicationControl(uiFactory.CreateApplicationControl(Context.Browser, Location.ActionCenter), true);
|
||||
}
|
||||
|
||||
if (Context.Settings.UserInterface.Taskbar.EnableTaskbar)
|
||||
{
|
||||
taskbar.AddApplicationControl(uiFactory.CreateApplicationControl(Context.Browser, Location.Taskbar), true);
|
||||
}
|
||||
|
||||
taskview.Add(Context.Browser);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info("Browser application is disabled for this session.");
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
logger.Info("Terminating browser...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateBrowser);
|
||||
|
||||
if (Context.Settings.Browser.EnableBrowser)
|
||||
{
|
||||
Context.Browser.Terminate();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info("Browser application was disabled for this session.");
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 System.Threading;
|
||||
using SafeExamBrowser.Communication.Contracts.Events;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
/// <summary>
|
||||
/// During application shutdown, it could happen that the client stops its communication host before the runtime had the chance to
|
||||
/// disconnect from it. This operation prevents the described race condition by waiting on the runtime to disconnect from the client.
|
||||
/// </summary>
|
||||
internal class ClientHostDisconnectionOperation : ClientOperation
|
||||
{
|
||||
private ILogger logger;
|
||||
private int timeout_ms;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public ClientHostDisconnectionOperation(ClientContext context, ILogger logger, int timeout_ms) : base(context)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.timeout_ms = timeout_ms;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_WaitRuntimeDisconnection);
|
||||
|
||||
if (Context.ClientHost.IsConnected)
|
||||
{
|
||||
var disconnected = false;
|
||||
var disconnectedEvent = new AutoResetEvent(false);
|
||||
var disconnectedEventHandler = new CommunicationEventHandler(() => disconnectedEvent.Set());
|
||||
|
||||
Context.ClientHost.RuntimeDisconnected += disconnectedEventHandler;
|
||||
|
||||
logger.Info("Waiting for runtime to disconnect from client communication host...");
|
||||
disconnected = disconnectedEvent.WaitOne(timeout_ms);
|
||||
|
||||
Context.ClientHost.RuntimeDisconnected -= disconnectedEventHandler;
|
||||
|
||||
if (disconnected)
|
||||
{
|
||||
logger.Info("The runtime has successfully disconnected from the client communication host.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error($"The runtime failed to disconnect within {timeout_ms / 1000} seconds!");
|
||||
|
||||
return OperationResult.Failed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info("The runtime has already disconnected from the client communication host.");
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
32
SafeExamBrowser.Client/Operations/ClientOperation.cs
Normal file
32
SafeExamBrowser.Client/Operations/ClientOperation.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.OperationModel.Events;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
/// <summary>
|
||||
/// The base implementation to be used for all operations in the client operation sequence.
|
||||
/// </summary>
|
||||
internal abstract class ClientOperation : IOperation
|
||||
{
|
||||
protected ClientContext Context { get; private set; }
|
||||
|
||||
public abstract event ActionRequiredEventHandler ActionRequired;
|
||||
public abstract event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public ClientOperation(ClientContext context)
|
||||
{
|
||||
Context = context;
|
||||
}
|
||||
|
||||
public abstract OperationResult Perform();
|
||||
public abstract OperationResult Revert();
|
||||
}
|
||||
}
|
59
SafeExamBrowser.Client/Operations/ClipboardOperation.cs
Normal file
59
SafeExamBrowser.Client/Operations/ClipboardOperation.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class ClipboardOperation : ClientOperation
|
||||
{
|
||||
private readonly IClipboard clipboard;
|
||||
private readonly ILogger logger;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public ClipboardOperation(ClientContext context, IClipboard clipboard, ILogger logger) : base(context)
|
||||
{
|
||||
this.clipboard = clipboard;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
InitializeClipboard();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
FinalizeClipboard();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
private void InitializeClipboard()
|
||||
{
|
||||
logger.Info("Initializing clipboard...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeClipboard);
|
||||
clipboard.Initialize(Context.Settings.Security.ClipboardPolicy);
|
||||
}
|
||||
|
||||
private void FinalizeClipboard()
|
||||
{
|
||||
logger.Info("Finalizing clipboard...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_FinalizeClipboard);
|
||||
clipboard.Terminate();
|
||||
}
|
||||
}
|
||||
}
|
56
SafeExamBrowser.Client/Operations/ConfigurationOperation.cs
Normal file
56
SafeExamBrowser.Client/Operations/ConfigurationOperation.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.Communication.Contracts.Proxies;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class ConfigurationOperation : ClientOperation
|
||||
{
|
||||
private readonly ILogger logger;
|
||||
private readonly IRuntimeProxy runtime;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public ConfigurationOperation(ClientContext context, ILogger logger, IRuntimeProxy runtime) : base(context)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
logger.Info("Initializing application configuration...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeConfiguration);
|
||||
|
||||
var communication = runtime.GetConfiguration();
|
||||
var configuration = communication.Value.Configuration;
|
||||
|
||||
Context.AppConfig = configuration.AppConfig;
|
||||
Context.SessionId = configuration.SessionId;
|
||||
Context.Settings = configuration.Settings;
|
||||
|
||||
logger.Info("Successfully retrieved the application configuration from the runtime.");
|
||||
logger.Info($" -> Client-ID: {Context.AppConfig.ClientId}");
|
||||
logger.Info($" -> Runtime-ID: {Context.AppConfig.RuntimeId}");
|
||||
logger.Info($" -> Session-ID: {Context.SessionId}");
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
56
SafeExamBrowser.Client/Operations/DisplayMonitorOperation.cs
Normal file
56
SafeExamBrowser.Client/Operations/DisplayMonitorOperation.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Display;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class DisplayMonitorOperation : ClientOperation
|
||||
{
|
||||
private readonly IDisplayMonitor displayMonitor;
|
||||
private readonly ILogger logger;
|
||||
private readonly ITaskbar taskbar;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public DisplayMonitorOperation(ClientContext context, IDisplayMonitor displayMonitor, ILogger logger, ITaskbar taskbar) : base(context)
|
||||
{
|
||||
this.displayMonitor = displayMonitor;
|
||||
this.logger = logger;
|
||||
this.taskbar = taskbar;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
logger.Info("Initializing working area...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeWorkingArea);
|
||||
|
||||
displayMonitor.InitializePrimaryDisplay(Context.Settings.UserInterface.Taskbar.EnableTaskbar ? taskbar.GetAbsoluteHeight() : 0);
|
||||
displayMonitor.StartMonitoringDisplayChanges();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
logger.Info("Restoring working area...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_RestoreWorkingArea);
|
||||
|
||||
displayMonitor.StopMonitoringDisplayChanges();
|
||||
displayMonitor.ResetPrimaryDisplay();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.Applications.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations.Events
|
||||
{
|
||||
internal class ApplicationInitializationFailedEventArgs : ActionRequiredEventArgs
|
||||
{
|
||||
internal string DisplayName { get; }
|
||||
internal string ExecutableName { get; }
|
||||
internal FactoryResult Result { get; }
|
||||
|
||||
internal ApplicationInitializationFailedEventArgs(string displayName, string executableName, FactoryResult result)
|
||||
{
|
||||
DisplayName = displayName;
|
||||
ExecutableName = executableName;
|
||||
Result = result;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.Events;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations.Events
|
||||
{
|
||||
internal class ApplicationNotFoundEventArgs : ActionRequiredEventArgs
|
||||
{
|
||||
internal string CustomPath { get; set; }
|
||||
internal string DisplayName { get; }
|
||||
internal string ExecutableName { get; }
|
||||
internal bool Success { get; set; }
|
||||
|
||||
internal ApplicationNotFoundEventArgs(string displayName, string executableName)
|
||||
{
|
||||
DisplayName = displayName;
|
||||
ExecutableName = executableName;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 System.Collections.Generic;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Applications;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations.Events
|
||||
{
|
||||
internal class ApplicationTerminationEventArgs : ActionRequiredEventArgs
|
||||
{
|
||||
internal IEnumerable<RunningApplication> RunningApplications { get; }
|
||||
internal bool TerminateProcesses { get; set; }
|
||||
|
||||
internal ApplicationTerminationEventArgs(IEnumerable<RunningApplication> runningApplications)
|
||||
{
|
||||
RunningApplications = runningApplications;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 System.Collections.Generic;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Applications;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations.Events
|
||||
{
|
||||
internal class ApplicationTerminationFailedEventArgs : ActionRequiredEventArgs
|
||||
{
|
||||
internal IEnumerable<RunningApplication> Applications { get; }
|
||||
|
||||
internal ApplicationTerminationFailedEventArgs(IEnumerable<RunningApplication> applications)
|
||||
{
|
||||
Applications = applications;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Keyboard;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class KeyboardInterceptorOperation : ClientOperation
|
||||
{
|
||||
private IKeyboardInterceptor keyboardInterceptor;
|
||||
private ILogger logger;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public KeyboardInterceptorOperation(ClientContext context, IKeyboardInterceptor keyboardInterceptor, ILogger logger) : base(context)
|
||||
{
|
||||
this.keyboardInterceptor = keyboardInterceptor;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
logger.Info("Starting keyboard interception...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_StartKeyboardInterception);
|
||||
|
||||
keyboardInterceptor.Start();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
logger.Info("Stopping keyboard interception...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_StopKeyboardInterception);
|
||||
|
||||
keyboardInterceptor.Stop();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Monitoring.Contracts.Mouse;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class MouseInterceptorOperation : ClientOperation
|
||||
{
|
||||
private ILogger logger;
|
||||
private IMouseInterceptor mouseInterceptor;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public MouseInterceptorOperation(ClientContext context, ILogger logger, IMouseInterceptor mouseInterceptor) : base(context)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.mouseInterceptor = mouseInterceptor;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
logger.Info("Starting mouse interception...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_StartMouseInterception);
|
||||
|
||||
mouseInterceptor.Start();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
logger.Info("Stopping mouse interception...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_StopMouseInterception);
|
||||
|
||||
mouseInterceptor.Stop();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
93
SafeExamBrowser.Client/Operations/ProctoringOperation.cs
Normal file
93
SafeExamBrowser.Client/Operations/ProctoringOperation.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Proctoring.Contracts;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class ProctoringOperation : ClientOperation
|
||||
{
|
||||
private readonly IActionCenter actionCenter;
|
||||
private readonly IProctoringController controller;
|
||||
private readonly ILogger logger;
|
||||
private readonly ITaskbar taskbar;
|
||||
private readonly IUserInterfaceFactory uiFactory;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public ProctoringOperation(
|
||||
IActionCenter actionCenter,
|
||||
ClientContext context,
|
||||
IProctoringController controller,
|
||||
ILogger logger,
|
||||
ITaskbar taskbar,
|
||||
IUserInterfaceFactory uiFactory) : base(context)
|
||||
{
|
||||
this.actionCenter = actionCenter;
|
||||
this.controller = controller;
|
||||
this.logger = logger;
|
||||
this.taskbar = taskbar;
|
||||
this.uiFactory = uiFactory;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
if (Context.Settings.Proctoring.Enabled)
|
||||
{
|
||||
logger.Info("Initializing proctoring...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeProctoring);
|
||||
|
||||
controller.Initialize(Context.Settings.Proctoring);
|
||||
|
||||
if (Context.Settings.SessionMode == SessionMode.Server && Context.Settings.Proctoring.ShowRaiseHandNotification)
|
||||
{
|
||||
actionCenter.AddNotificationControl(uiFactory.CreateRaiseHandControl(controller, Location.ActionCenter, Context.Settings.Proctoring));
|
||||
taskbar.AddNotificationControl(uiFactory.CreateRaiseHandControl(controller, Location.Taskbar, Context.Settings.Proctoring));
|
||||
}
|
||||
|
||||
foreach (var notification in controller.Notifications)
|
||||
{
|
||||
actionCenter.AddNotificationControl(uiFactory.CreateNotificationControl(notification, Location.ActionCenter));
|
||||
|
||||
if (Context.Settings.Proctoring.ShowTaskbarNotification)
|
||||
{
|
||||
taskbar.AddNotificationControl(uiFactory.CreateNotificationControl(notification, Location.Taskbar));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
if (Context.Settings.Proctoring.Enabled)
|
||||
{
|
||||
logger.Info("Terminating proctoring...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateProctoring);
|
||||
|
||||
controller.Terminate();
|
||||
|
||||
foreach (var notification in controller.Notifications)
|
||||
{
|
||||
notification.Terminate();
|
||||
}
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 System;
|
||||
using SafeExamBrowser.Communication.Contracts.Proxies;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class RuntimeConnectionOperation : ClientOperation
|
||||
{
|
||||
private ILogger logger;
|
||||
private IRuntimeProxy runtime;
|
||||
private Guid token;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public RuntimeConnectionOperation(ClientContext context, ILogger logger, IRuntimeProxy runtime, Guid token) : base(context)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.runtime = runtime;
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
logger.Info("Initializing runtime connection...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeRuntimeConnection);
|
||||
|
||||
var connected = runtime.Connect(token);
|
||||
|
||||
if (connected)
|
||||
{
|
||||
logger.Info("Successfully connected to the runtime.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Failed to connect to the runtime. Aborting startup...");
|
||||
}
|
||||
|
||||
return connected ? OperationResult.Success : OperationResult.Failed;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
logger.Info("Closing runtime connection...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_CloseRuntimeConnection);
|
||||
|
||||
if (runtime.IsConnected)
|
||||
{
|
||||
var success = runtime.Disconnect();
|
||||
|
||||
if (success)
|
||||
{
|
||||
logger.Info("Successfully disconnected from the runtime.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Failed to disconnect from the runtime!");
|
||||
}
|
||||
|
||||
return success ? OperationResult.Success : OperationResult.Failed;
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
64
SafeExamBrowser.Client/Operations/ServerOperation.cs
Normal file
64
SafeExamBrowser.Client/Operations/ServerOperation.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Server.Contracts;
|
||||
using SafeExamBrowser.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class ServerOperation : ClientOperation
|
||||
{
|
||||
private readonly ILogger logger;
|
||||
private readonly IServerProxy server;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public ServerOperation(ClientContext context, ILogger logger, IServerProxy server) : base(context)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
if (Context.Settings.SessionMode == SessionMode.Server)
|
||||
{
|
||||
logger.Info("Initializing server...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeServer);
|
||||
|
||||
server.Initialize(
|
||||
Context.AppConfig.ServerApi,
|
||||
Context.AppConfig.ServerConnectionToken,
|
||||
Context.AppConfig.ServerExamId,
|
||||
Context.AppConfig.ServerOauth2Token,
|
||||
Context.Settings.Server);
|
||||
server.StartConnectivity();
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
if (Context.Settings?.SessionMode == SessionMode.Server)
|
||||
{
|
||||
logger.Info("Finalizing server...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_FinalizeServer);
|
||||
|
||||
server.StopConnectivity();
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
371
SafeExamBrowser.Client/Operations/ShellOperation.cs
Normal file
371
SafeExamBrowser.Client/Operations/ShellOperation.cs
Normal file
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 System.Linq;
|
||||
using SafeExamBrowser.Core.Contracts.Notifications;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.SystemComponents.Contracts;
|
||||
using SafeExamBrowser.SystemComponents.Contracts.Audio;
|
||||
using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
|
||||
using SafeExamBrowser.SystemComponents.Contracts.Network;
|
||||
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Shell;
|
||||
using SafeExamBrowser.WindowsApi.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Client.Operations
|
||||
{
|
||||
internal class ShellOperation : ClientOperation
|
||||
{
|
||||
private readonly IActionCenter actionCenter;
|
||||
private readonly IAudio audio;
|
||||
private readonly INotification aboutNotification;
|
||||
private readonly IKeyboard keyboard;
|
||||
private readonly ILogger logger;
|
||||
private readonly INotification logNotification;
|
||||
private readonly INativeMethods nativeMethods;
|
||||
private readonly INetworkAdapter networkAdapter;
|
||||
private readonly IPowerSupply powerSupply;
|
||||
private readonly ISystemInfo systemInfo;
|
||||
private readonly ITaskbar taskbar;
|
||||
private readonly ITaskview taskview;
|
||||
private readonly IText text;
|
||||
private readonly IUserInterfaceFactory uiFactory;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public ShellOperation(
|
||||
IActionCenter actionCenter,
|
||||
IAudio audio,
|
||||
INotification aboutNotification,
|
||||
ClientContext context,
|
||||
IKeyboard keyboard,
|
||||
ILogger logger,
|
||||
INotification logNotification,
|
||||
INativeMethods nativeMethods,
|
||||
INetworkAdapter networkAdapter,
|
||||
IPowerSupply powerSupply,
|
||||
ISystemInfo systemInfo,
|
||||
ITaskbar taskbar,
|
||||
ITaskview taskview,
|
||||
IText text,
|
||||
IUserInterfaceFactory uiFactory) : base(context)
|
||||
{
|
||||
this.aboutNotification = aboutNotification;
|
||||
this.actionCenter = actionCenter;
|
||||
this.audio = audio;
|
||||
this.keyboard = keyboard;
|
||||
this.logger = logger;
|
||||
this.logNotification = logNotification;
|
||||
this.nativeMethods = nativeMethods;
|
||||
this.networkAdapter = networkAdapter;
|
||||
this.powerSupply = powerSupply;
|
||||
this.systemInfo = systemInfo;
|
||||
this.text = text;
|
||||
this.taskbar = taskbar;
|
||||
this.taskview = taskview;
|
||||
this.uiFactory = uiFactory;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
logger.Info("Initializing shell...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeShell);
|
||||
|
||||
InitializeSystemComponents();
|
||||
InitializeActionCenter();
|
||||
InitializeTaskbar();
|
||||
InitializeTaskview();
|
||||
InitializeActivators();
|
||||
InitializeAlwaysOnState();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
logger.Info("Terminating shell...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateShell);
|
||||
|
||||
TerminateActivators();
|
||||
TerminateNotifications();
|
||||
TerminateSystemComponents();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
private void InitializeActivators()
|
||||
{
|
||||
foreach (var activator in Context.Activators)
|
||||
{
|
||||
if (Context.Settings.UserInterface.ActionCenter.EnableActionCenter && activator is IActionCenterActivator actionCenterActivator)
|
||||
{
|
||||
actionCenter.Register(actionCenterActivator);
|
||||
actionCenterActivator.Start();
|
||||
}
|
||||
|
||||
if (Context.Settings.Keyboard.AllowAltTab && activator is ITaskviewActivator taskViewActivator)
|
||||
{
|
||||
taskview.Register(taskViewActivator);
|
||||
taskViewActivator.Start();
|
||||
}
|
||||
|
||||
if (Context.Settings.Security.AllowTermination && activator is ITerminationActivator terminationActivator)
|
||||
{
|
||||
terminationActivator.Start();
|
||||
}
|
||||
|
||||
if (Context.Settings.UserInterface.Taskbar.EnableTaskbar && activator is ITaskbarActivator taskbarActivator)
|
||||
{
|
||||
taskbar.Register(taskbarActivator);
|
||||
taskbarActivator.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeActionCenter()
|
||||
{
|
||||
if (Context.Settings.UserInterface.ActionCenter.EnableActionCenter)
|
||||
{
|
||||
logger.Info("Initializing action center...");
|
||||
actionCenter.InitializeText(text);
|
||||
|
||||
InitializeApplicationsFor(Location.ActionCenter);
|
||||
InitializeAboutNotificationForActionCenter();
|
||||
InitializeAudioForActionCenter();
|
||||
InitializeClockForActionCenter();
|
||||
InitializeLogNotificationForActionCenter();
|
||||
InitializeKeyboardLayoutForActionCenter();
|
||||
InitializeNetworkForActionCenter();
|
||||
InitializePowerSupplyForActionCenter();
|
||||
InitializeQuitButtonForActionCenter();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info("Action center is disabled, skipping initialization.");
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeAlwaysOnState()
|
||||
{
|
||||
var display = Context.Settings.Display.AlwaysOn;
|
||||
var system = Context.Settings.System.AlwaysOn;
|
||||
|
||||
nativeMethods.SetAlwaysOnState(display, system);
|
||||
|
||||
logger.Info($"Display(s) will {(display ? "be always on" : "use the operating system configuration and may turn off")}.");
|
||||
logger.Info($"System will {(system ? "be always on" : "use the operating system configuration and may enter sleep mode or standby")}.");
|
||||
}
|
||||
|
||||
private void InitializeTaskbar()
|
||||
{
|
||||
if (Context.Settings.UserInterface.Taskbar.EnableTaskbar)
|
||||
{
|
||||
logger.Info("Initializing taskbar...");
|
||||
taskbar.InitializeText(text);
|
||||
|
||||
InitializeApplicationsFor(Location.Taskbar);
|
||||
InitializeAboutNotificationForTaskbar();
|
||||
InitializeLogNotificationForTaskbar();
|
||||
InitializePowerSupplyForTaskbar();
|
||||
InitializeNetworkForTaskbar();
|
||||
InitializeAudioForTaskbar();
|
||||
InitializeKeyboardLayoutForTaskbar();
|
||||
InitializeClockForTaskbar();
|
||||
InitializeQuitButtonForTaskbar();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info("Taskbar is disabled, skipping initialization.");
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeTaskview()
|
||||
{
|
||||
logger.Info("Initializing task view...");
|
||||
|
||||
foreach (var application in Context.Applications)
|
||||
{
|
||||
taskview.Add(application);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeApplicationsFor(Location location)
|
||||
{
|
||||
foreach (var application in Context.Applications)
|
||||
{
|
||||
var settings = Context.Settings.Applications.Whitelist.First(a => a.Id == application.Id);
|
||||
|
||||
if (settings.ShowInShell)
|
||||
{
|
||||
var control = uiFactory.CreateApplicationControl(application, location);
|
||||
|
||||
switch (location)
|
||||
{
|
||||
case Location.ActionCenter:
|
||||
actionCenter.AddApplicationControl(control);
|
||||
break;
|
||||
case Location.Taskbar:
|
||||
taskbar.AddApplicationControl(control);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeSystemComponents()
|
||||
{
|
||||
audio.Initialize();
|
||||
keyboard.Initialize();
|
||||
networkAdapter.Initialize();
|
||||
powerSupply.Initialize();
|
||||
}
|
||||
|
||||
private void InitializeAboutNotificationForActionCenter()
|
||||
{
|
||||
if (Context.Settings.UserInterface.ActionCenter.ShowApplicationInfo)
|
||||
{
|
||||
actionCenter.AddNotificationControl(uiFactory.CreateNotificationControl(aboutNotification, Location.ActionCenter));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeAboutNotificationForTaskbar()
|
||||
{
|
||||
if (Context.Settings.UserInterface.Taskbar.ShowApplicationInfo)
|
||||
{
|
||||
taskbar.AddNotificationControl(uiFactory.CreateNotificationControl(aboutNotification, Location.Taskbar));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeAudioForActionCenter()
|
||||
{
|
||||
if (Context.Settings.UserInterface.ActionCenter.ShowAudio)
|
||||
{
|
||||
actionCenter.AddSystemControl(uiFactory.CreateAudioControl(audio, Location.ActionCenter));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeAudioForTaskbar()
|
||||
{
|
||||
if (Context.Settings.UserInterface.Taskbar.ShowAudio)
|
||||
{
|
||||
taskbar.AddSystemControl(uiFactory.CreateAudioControl(audio, Location.Taskbar));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeClockForActionCenter()
|
||||
{
|
||||
actionCenter.ShowClock = Context.Settings.UserInterface.ActionCenter.ShowClock;
|
||||
}
|
||||
|
||||
private void InitializeClockForTaskbar()
|
||||
{
|
||||
taskbar.ShowClock = Context.Settings.UserInterface.Taskbar.ShowClock;
|
||||
}
|
||||
|
||||
private void InitializeLogNotificationForActionCenter()
|
||||
{
|
||||
if (Context.Settings.UserInterface.ActionCenter.ShowApplicationLog)
|
||||
{
|
||||
actionCenter.AddNotificationControl(uiFactory.CreateNotificationControl(logNotification, Location.ActionCenter));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeLogNotificationForTaskbar()
|
||||
{
|
||||
if (Context.Settings.UserInterface.Taskbar.ShowApplicationLog)
|
||||
{
|
||||
taskbar.AddNotificationControl(uiFactory.CreateNotificationControl(logNotification, Location.Taskbar));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeKeyboardLayoutForActionCenter()
|
||||
{
|
||||
if (Context.Settings.UserInterface.ActionCenter.ShowKeyboardLayout)
|
||||
{
|
||||
actionCenter.AddSystemControl(uiFactory.CreateKeyboardLayoutControl(keyboard, Location.ActionCenter));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeKeyboardLayoutForTaskbar()
|
||||
{
|
||||
if (Context.Settings.UserInterface.Taskbar.ShowKeyboardLayout)
|
||||
{
|
||||
taskbar.AddSystemControl(uiFactory.CreateKeyboardLayoutControl(keyboard, Location.Taskbar));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializePowerSupplyForActionCenter()
|
||||
{
|
||||
if (systemInfo.HasBattery)
|
||||
{
|
||||
actionCenter.AddSystemControl(uiFactory.CreatePowerSupplyControl(powerSupply, Location.ActionCenter));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializePowerSupplyForTaskbar()
|
||||
{
|
||||
if (systemInfo.HasBattery)
|
||||
{
|
||||
taskbar.AddSystemControl(uiFactory.CreatePowerSupplyControl(powerSupply, Location.Taskbar));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeQuitButtonForActionCenter()
|
||||
{
|
||||
actionCenter.ShowQuitButton = Context.Settings.Security.AllowTermination;
|
||||
}
|
||||
|
||||
private void InitializeQuitButtonForTaskbar()
|
||||
{
|
||||
taskbar.ShowQuitButton = Context.Settings.Security.AllowTermination;
|
||||
}
|
||||
|
||||
private void InitializeNetworkForActionCenter()
|
||||
{
|
||||
if (Context.Settings.UserInterface.ActionCenter.ShowNetwork)
|
||||
{
|
||||
actionCenter.AddSystemControl(uiFactory.CreateNetworkControl(networkAdapter, Location.ActionCenter));
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeNetworkForTaskbar()
|
||||
{
|
||||
if (Context.Settings.UserInterface.Taskbar.ShowNetwork)
|
||||
{
|
||||
taskbar.AddSystemControl(uiFactory.CreateNetworkControl(networkAdapter, Location.Taskbar));
|
||||
}
|
||||
}
|
||||
|
||||
private void TerminateActivators()
|
||||
{
|
||||
foreach (var activator in Context.Activators)
|
||||
{
|
||||
activator.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void TerminateNotifications()
|
||||
{
|
||||
aboutNotification.Terminate();
|
||||
logNotification.Terminate();
|
||||
}
|
||||
|
||||
private void TerminateSystemComponents()
|
||||
{
|
||||
audio.Terminate();
|
||||
keyboard.Terminate();
|
||||
networkAdapter.Terminate();
|
||||
powerSupply.Terminate();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user