From 758b61084aff84d8b634698e55bf2137f0ec5120 Mon Sep 17 00:00:00 2001 From: dbuechel Date: Fri, 16 Aug 2019 08:26:11 +0200 Subject: [PATCH] SEBWIN-303: Implemented audio settings. --- SafeExamBrowser.Client/CompositionRoot.cs | 12 ++--- .../ConfigurationData/DataMapper.Audio.cs | 39 +++++++++++++++ .../ConfigurationData/DataMapper.cs | 17 +++++++ .../ConfigurationData/Keys.cs | 7 +++ .../SafeExamBrowser.Configuration.csproj | 3 ++ .../Configuration/Settings/AudioSettings.cs | 34 +++++++++++++ .../Configuration/Settings/Settings.cs | 6 +++ .../SafeExamBrowser.Contracts.csproj | 1 + SafeExamBrowser.SystemComponents/Audio.cs | 49 ++++++++++++++++--- 9 files changed, 154 insertions(+), 14 deletions(-) create mode 100644 SafeExamBrowser.Configuration/ConfigurationData/DataMapper.Audio.cs create mode 100644 SafeExamBrowser.Contracts/Configuration/Settings/AudioSettings.cs diff --git a/SafeExamBrowser.Client/CompositionRoot.cs b/SafeExamBrowser.Client/CompositionRoot.cs index d9ef0876..590a4901 100644 --- a/SafeExamBrowser.Client/CompositionRoot.cs +++ b/SafeExamBrowser.Client/CompositionRoot.cs @@ -67,10 +67,6 @@ namespace SafeExamBrowser.Client private IProcessMonitor processMonitor; private INativeMethods nativeMethods; private IRuntimeProxy runtimeProxy; - private ISystemComponent audio; - private ISystemComponent keyboardLayout; - private ISystemComponent powerSupply; - private ISystemComponent wirelessNetwork; private ISystemInfo systemInfo; private ITaskbar taskbar; private ITerminationActivator terminationActivator; @@ -94,17 +90,13 @@ namespace SafeExamBrowser.Client InitializeText(); actionCenter = BuildActionCenter(); - audio = new Audio(new ModuleLogger(logger, nameof(Audio)), text); - keyboardLayout = new KeyboardLayout(new ModuleLogger(logger, nameof(KeyboardLayout)), text); messageBox = BuildMessageBox(); - powerSupply = new PowerSupply(new ModuleLogger(logger, nameof(PowerSupply)), text); processMonitor = new ProcessMonitor(new ModuleLogger(logger, nameof(ProcessMonitor)), nativeMethods); uiFactory = BuildUserInterfaceFactory(); runtimeProxy = new RuntimeProxy(runtimeHostUri, new ProxyObjectFactory(), new ModuleLogger(logger, nameof(RuntimeProxy)), Interlocutor.Client); taskbar = BuildTaskbar(); terminationActivator = new TerminationActivator(new ModuleLogger(logger, nameof(TerminationActivator))); windowMonitor = new WindowMonitor(new ModuleLogger(logger, nameof(WindowMonitor)), nativeMethods); - wirelessNetwork = new WirelessNetwork(new ModuleLogger(logger, nameof(WirelessNetwork)), text); var displayMonitor = new DisplayMonitor(new ModuleLogger(logger, nameof(DisplayMonitor)), nativeMethods, systemInfo); var explorerShell = new ExplorerShell(new ModuleLogger(logger, nameof(ExplorerShell)), nativeMethods); @@ -263,8 +255,12 @@ namespace SafeExamBrowser.Client { var aboutInfo = new AboutNotificationInfo(text); var aboutController = new AboutNotificationController(configuration.AppConfig, uiFactory); + var audio = new Audio(configuration.Settings.Audio, new ModuleLogger(logger, nameof(Audio)), text); + var keyboardLayout = new KeyboardLayout(new ModuleLogger(logger, nameof(KeyboardLayout)), text); var logInfo = new LogNotificationInfo(text); var logController = new LogNotificationController(logger, uiFactory); + var powerSupply = new PowerSupply(new ModuleLogger(logger, nameof(PowerSupply)), text); + var wirelessNetwork = new WirelessNetwork(new ModuleLogger(logger, nameof(WirelessNetwork)), text); var activators = new IActionCenterActivator[] { new KeyboardActivator(new ModuleLogger(logger, nameof(KeyboardActivator))), diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.Audio.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.Audio.cs new file mode 100644 index 00000000..8692dd6d --- /dev/null +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.Audio.cs @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 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 SafeExamBrowser.Contracts.Configuration.Settings; + +namespace SafeExamBrowser.Configuration.ConfigurationData +{ + internal partial class DataMapper + { + private void MapInitialVolumeLevel(Settings settings, object value) + { + if (value is int volume) + { + settings.Audio.InitialVolume = volume; + } + } + + private void MapMuteAudio(Settings settings, object value) + { + if (value is bool mute) + { + settings.Audio.MuteAudio = mute; + } + } + + private void MapSetInitialVolumeLevel(Settings settings, object value) + { + if (value is bool initialize) + { + settings.Audio.InitializeVolume = initialize; + } + } + } +} diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.cs index d6f35d9d..eb7bf305 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataMapper.cs @@ -17,6 +17,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData { foreach (var item in rawData) { + MapAudioSettings(item.Key, item.Value, settings); MapBrowserSettings(item.Key, item.Value, settings); MapConfigurationFileSettings(item.Key, item.Value, settings); MapGeneralSettings(item.Key, item.Value, settings); @@ -30,6 +31,22 @@ namespace SafeExamBrowser.Configuration.ConfigurationData MapUserAgentMode(rawData, settings); } + private void MapAudioSettings(string key, object value, Settings settings) + { + switch (key) + { + case Keys.Audio.InitialVolumeLevel: + MapInitialVolumeLevel(settings, value); + break; + case Keys.Audio.MuteAudio: + MapMuteAudio(settings, value); + break; + case Keys.Audio.SetInitialVolumeLevel: + MapSetInitialVolumeLevel(settings, value); + break; + } + } + private void MapBrowserSettings(string key, object value, Settings settings) { switch (key) diff --git a/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs b/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs index b10c1fb4..469827f2 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs @@ -18,6 +18,13 @@ namespace SafeExamBrowser.Configuration.ConfigurationData { } + internal static class Audio + { + internal const string InitialVolumeLevel = "audioVolumeLevel"; + internal const string MuteAudio = "audioMute"; + internal const string SetInitialVolumeLevel = "audioSetVolumeLevel"; + } + internal static class Browser { internal const string AllowConfigurationDownloads = "downloadAndOpenSebConfig"; diff --git a/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj b/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj index 83ff44e4..27b02d5f 100644 --- a/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj +++ b/SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj @@ -66,6 +66,9 @@ + + DataMapper.cs + DataMapper.cs diff --git a/SafeExamBrowser.Contracts/Configuration/Settings/AudioSettings.cs b/SafeExamBrowser.Contracts/Configuration/Settings/AudioSettings.cs new file mode 100644 index 00000000..e76ec0b6 --- /dev/null +++ b/SafeExamBrowser.Contracts/Configuration/Settings/AudioSettings.cs @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019 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; + +namespace SafeExamBrowser.Contracts.Configuration.Settings +{ + /// + /// Defines all configuration options for the audio device of the computer. + /// + [Serializable] + public class AudioSettings + { + /// + /// Defines whether the audio volume should be initialized to the value of during application startup. + /// + public bool InitializeVolume { get; set; } + + /// + /// Defines the initial audio volume (from 0 to 100) to be used if is active. + /// + public int InitialVolume { get; set; } + + /// + /// Defines whether the audio device should be muted during application startup. + /// + public bool MuteAudio { get; set; } + } +} diff --git a/SafeExamBrowser.Contracts/Configuration/Settings/Settings.cs b/SafeExamBrowser.Contracts/Configuration/Settings/Settings.cs index f9e70d90..ac9fd0ed 100644 --- a/SafeExamBrowser.Contracts/Configuration/Settings/Settings.cs +++ b/SafeExamBrowser.Contracts/Configuration/Settings/Settings.cs @@ -32,6 +32,11 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings /// public bool AllowApplicationLogAccess { get; set; } + /// + /// All audio-related settings. + /// + public AudioSettings Audio { get; set; } + /// /// All browser-related settings. /// @@ -85,6 +90,7 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings public Settings() { ActionCenter = new ActionCenterSettings(); + Audio = new AudioSettings(); Browser = new BrowserSettings(); Keyboard = new KeyboardSettings(); Mouse = new MouseSettings(); diff --git a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj index 993cd2c1..9a64bc39 100644 --- a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj +++ b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj @@ -84,6 +84,7 @@ + diff --git a/SafeExamBrowser.SystemComponents/Audio.cs b/SafeExamBrowser.SystemComponents/Audio.cs index 889d2c6f..4fbed00c 100644 --- a/SafeExamBrowser.SystemComponents/Audio.cs +++ b/SafeExamBrowser.SystemComponents/Audio.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; using System.Linq; using NAudio.CoreAudioApi; +using SafeExamBrowser.Contracts.Configuration.Settings; using SafeExamBrowser.Contracts.I18n; using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.SystemComponents; @@ -21,15 +22,18 @@ namespace SafeExamBrowser.SystemComponents { private readonly object @lock = new object(); + private AudioSettings settings; private MMDevice audioDevice; private string audioDeviceShortName; private List controls; + private float originalVolume; private ILogger logger; private IText text; - public Audio(ILogger logger, IText text) + public Audio(AudioSettings settings, ILogger logger, IText text) { this.controls = new List(); + this.settings = settings; this.logger = logger; this.text = text; } @@ -64,9 +68,8 @@ namespace SafeExamBrowser.SystemComponents { if (audioDevice != default(MMDevice)) { - audioDevice.AudioEndpointVolume.OnVolumeNotification -= AudioEndpointVolume_OnVolumeNotification; - audioDevice.Dispose(); - logger.Info("Stopped monitoring the audio device."); + RevertSettings(); + FinalizeAudioDevice(); } foreach (var control in controls) @@ -100,9 +103,43 @@ namespace SafeExamBrowser.SystemComponents logger.Info("Started monitoring the audio device."); } + private void FinalizeAudioDevice() + { + audioDevice.AudioEndpointVolume.OnVolumeNotification -= AudioEndpointVolume_OnVolumeNotification; + audioDevice.Dispose(); + logger.Info("Stopped monitoring the audio device."); + } + private void InitializeSettings() { - // TODO: Mute on startup & initial volume! + if (settings.InitializeVolume) + { + originalVolume = audioDevice.AudioEndpointVolume.MasterVolumeLevelScalar; + logger.Info($"Saved original volume of {Math.Round(originalVolume * 100)}%."); + audioDevice.AudioEndpointVolume.MasterVolumeLevelScalar = settings.InitialVolume / 100f; + logger.Info($"Set initial volume to {settings.InitialVolume}%."); + } + + if (settings.MuteAudio) + { + audioDevice.AudioEndpointVolume.Mute = true; + logger.Info("Muted audio device."); + } + } + + private void RevertSettings() + { + if (settings.InitializeVolume) + { + audioDevice.AudioEndpointVolume.MasterVolumeLevelScalar = originalVolume; + logger.Info($"Reverted volume to original value of {Math.Round(originalVolume * 100)}%."); + } + + if (settings.MuteAudio) + { + audioDevice.AudioEndpointVolume.Mute = false; + logger.Info("Unmuted audio device."); + } } private void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data) @@ -111,7 +148,7 @@ namespace SafeExamBrowser.SystemComponents { var info = BuildInfoText(data.MasterVolume, data.Muted); - logger.Debug($"Detected audio device change: Volume {data.MasterVolume * 100}, {(data.Muted ? "muted" : "unmuted")}"); + logger.Debug($"Volume {data.MasterVolume * 100}%, {(data.Muted ? "muted" : "unmuted")}"); foreach (var control in controls) {