/* * Copyright (c) 2022 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 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; 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 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, 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.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(); 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.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.Taskbar.EnableTaskbar && activator is ITaskbarActivator taskbarActivator) { taskbar.Register(taskbarActivator); taskbarActivator.Start(); } } } private void InitializeActionCenter() { if (Context.Settings.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 InitializeTaskbar() { if (Context.Settings.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.ActionCenter.ShowApplicationInfo) { actionCenter.AddNotificationControl(uiFactory.CreateNotificationControl(aboutNotification, Location.ActionCenter)); } } private void InitializeAboutNotificationForTaskbar() { if (Context.Settings.Taskbar.ShowApplicationInfo) { taskbar.AddNotificationControl(uiFactory.CreateNotificationControl(aboutNotification, Location.Taskbar)); } } private void InitializeAudioForActionCenter() { if (Context.Settings.ActionCenter.ShowAudio) { actionCenter.AddSystemControl(uiFactory.CreateAudioControl(audio, Location.ActionCenter)); } } private void InitializeAudioForTaskbar() { if (Context.Settings.Taskbar.ShowAudio) { taskbar.AddSystemControl(uiFactory.CreateAudioControl(audio, Location.Taskbar)); } } private void InitializeClockForActionCenter() { actionCenter.ShowClock = Context.Settings.ActionCenter.ShowClock; } private void InitializeClockForTaskbar() { taskbar.ShowClock = Context.Settings.Taskbar.ShowClock; } private void InitializeLogNotificationForActionCenter() { if (Context.Settings.ActionCenter.ShowApplicationLog) { actionCenter.AddNotificationControl(uiFactory.CreateNotificationControl(logNotification, Location.ActionCenter)); } } private void InitializeLogNotificationForTaskbar() { if (Context.Settings.Taskbar.ShowApplicationLog) { taskbar.AddNotificationControl(uiFactory.CreateNotificationControl(logNotification, Location.Taskbar)); } } private void InitializeKeyboardLayoutForActionCenter() { if (Context.Settings.ActionCenter.ShowKeyboardLayout) { actionCenter.AddSystemControl(uiFactory.CreateKeyboardLayoutControl(keyboard, Location.ActionCenter)); } } private void InitializeKeyboardLayoutForTaskbar() { if (Context.Settings.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.ActionCenter.ShowNetwork) { actionCenter.AddSystemControl(uiFactory.CreateNetworkControl(networkAdapter, Location.ActionCenter)); } } private void InitializeNetworkForTaskbar() { if (Context.Settings.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(); } } }