SEBWIN-303: Implemented audio settings.

This commit is contained in:
dbuechel 2019-08-16 08:26:11 +02:00
parent 4381be2647
commit 758b61084a
9 changed files with 154 additions and 14 deletions

View file

@ -67,10 +67,6 @@ namespace SafeExamBrowser.Client
private IProcessMonitor processMonitor;
private INativeMethods nativeMethods;
private IRuntimeProxy runtimeProxy;
private ISystemComponent<ISystemAudioControl> audio;
private ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout;
private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
private ISystemComponent<ISystemWirelessNetworkControl> 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))),

View file

@ -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;
}
}
}
}

View file

@ -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)

View file

@ -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";

View file

@ -66,6 +66,9 @@
<Compile Include="DataFormats\BinarySerializer.cs" />
<Compile Include="DataFormats\BinaryBlock.cs" />
<Compile Include="ConfigurationData\DataMapper.cs" />
<Compile Include="ConfigurationData\DataMapper.Audio.cs">
<DependentUpon>DataMapper.cs</DependentUpon>
</Compile>
<Compile Include="ConfigurationData\DataMapper.Browser.cs">
<DependentUpon>DataMapper.cs</DependentUpon>
</Compile>

View file

@ -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
{
/// <summary>
/// Defines all configuration options for the audio device of the computer.
/// </summary>
[Serializable]
public class AudioSettings
{
/// <summary>
/// Defines whether the audio volume should be initialized to the value of <see cref="InitialVolume"/> during application startup.
/// </summary>
public bool InitializeVolume { get; set; }
/// <summary>
/// Defines the initial audio volume (from 0 to 100) to be used if <see cref="InitializeVolume"/> is active.
/// </summary>
public int InitialVolume { get; set; }
/// <summary>
/// Defines whether the audio device should be muted during application startup.
/// </summary>
public bool MuteAudio { get; set; }
}
}

View file

@ -32,6 +32,11 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
/// </summary>
public bool AllowApplicationLogAccess { get; set; }
/// <summary>
/// All audio-related settings.
/// </summary>
public AudioSettings Audio { get; set; }
/// <summary>
/// All browser-related settings.
/// </summary>
@ -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();

View file

@ -84,6 +84,7 @@
<Compile Include="Configuration\SaveStatus.cs" />
<Compile Include="Configuration\ServiceConfiguration.cs" />
<Compile Include="Configuration\Settings\ActionCenterSettings.cs" />
<Compile Include="Configuration\Settings\AudioSettings.cs" />
<Compile Include="Configuration\Settings\BrowserWindowSettings.cs" />
<Compile Include="Configuration\Settings\ServiceSettings.cs" />
<Compile Include="Configuration\Settings\UserInterfaceMode.cs" />

View file

@ -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<ISystemAudioControl> 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<ISystemAudioControl>();
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)
{