Working on the wireless network component (IMPORTANT: The commited code is not yet working, I have to find a way to check whether the Wi-Fi is turned off via hard- or software!).

This commit is contained in:
dbuechel 2017-11-13 10:26:30 +01:00
parent a118f52ee3
commit 396aa56bd5
21 changed files with 593 additions and 3 deletions

View file

@ -90,6 +90,8 @@
<Compile Include="SystemComponents\BatteryChargeStatus.cs" />
<Compile Include="SystemComponents\IKeyboardLayout.cs" />
<Compile Include="SystemComponents\ISystemComponent.cs" />
<Compile Include="SystemComponents\IWirelessNetwork.cs" />
<Compile Include="SystemComponents\WirelessNetworkStatus.cs" />
<Compile Include="UserInterface\IBrowserControl.cs" />
<Compile Include="UserInterface\IBrowserWindow.cs" />
<Compile Include="UserInterface\IMessageBox.cs" />
@ -98,6 +100,7 @@
<Compile Include="UserInterface\Taskbar\ISystemKeyboardLayoutControl.cs" />
<Compile Include="UserInterface\Taskbar\ISystemPowerSupplyControl.cs" />
<Compile Include="UserInterface\Taskbar\ISystemControl.cs" />
<Compile Include="UserInterface\Taskbar\ISystemWirelessNetworkControl.cs" />
<Compile Include="UserInterface\Taskbar\ITaskbar.cs" />
<Compile Include="I18n\ITextResource.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2017 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.SystemComponents
{
public interface IWirelessNetwork
{
/// <summary>
/// The unique identifier of the network.
/// </summary>
Guid Id { get; }
/// <summary>
/// The network name.
/// </summary>
string Name { get; }
/// <summary>
/// The signal strength of this network, as percentage.
/// </summary>
int SignalStrength { get; }
/// <summary>
/// The connection status of this network.
/// </summary>
WirelessNetworkStatus Status { get; }
}
}

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2017 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/.
*/
namespace SafeExamBrowser.Contracts.SystemComponents
{
public enum WirelessNetworkStatus
{
Undefined = 0,
Connected,
Disconnected
}
}

View file

@ -55,5 +55,10 @@ namespace SafeExamBrowser.Contracts.UserInterface
/// Creates a new splash screen which runs on its own thread.
/// </summary>
ISplashScreen CreateSplashScreen(ISettings settings, IText text);
/// <summary>
/// Creates a system control which allows to change the wireless network connection of the computer.
/// </summary>
ISystemWirelessNetworkControl CreateWirelessNetworkControl();
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2017 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.Collections.Generic;
using SafeExamBrowser.Contracts.SystemComponents;
namespace SafeExamBrowser.Contracts.UserInterface.Taskbar
{
public delegate void WirelessNetworkSelectedEventHandler(IWirelessNetwork network);
public interface ISystemWirelessNetworkControl : ISystemControl
{
/// <summary>
/// Defines whether the computer has a wireless network adapter.
/// </summary>
bool HasWirelessNetworkAdapter { set; }
/// <summary>
/// Sets the current wireless network status.
/// </summary>
WirelessNetworkStatus NetworkStatus { set; }
/// <summary>
/// Event fired when the user selected a wireless network.
/// </summary>
event WirelessNetworkSelectedEventHandler NetworkSelected;
/// <summary>
/// Updates the list of available networks.
/// </summary>
void Update(IEnumerable<IWirelessNetwork> networks);
}
}

View file

@ -27,6 +27,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
private Mock<ISplashScreen> splashScreenMock;
private Mock<ISystemComponent<ISystemKeyboardLayoutControl>> keyboardLayoutMock;
private Mock<ISystemComponent<ISystemPowerSupplyControl>> powerSupplyMock;
private Mock<ISystemComponent<ISystemWirelessNetworkControl>> wirelessNetworkMock;
private Mock<ISystemInfo> systemInfoMock;
private Mock<ITaskbar> taskbarMock;
private Mock<IText> textMock;
@ -42,6 +43,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
splashScreenMock = new Mock<ISplashScreen>();
keyboardLayoutMock = new Mock<ISystemComponent<ISystemKeyboardLayoutControl>>();
powerSupplyMock = new Mock<ISystemComponent<ISystemPowerSupplyControl>>();
wirelessNetworkMock = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
systemInfoMock = new Mock<ISystemInfo>();
taskbarMock = new Mock<ITaskbar>();
textMock = new Mock<IText>();
@ -49,6 +51,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
settingsMock.SetupGet(s => s.AllowApplicationLog).Returns(true);
settingsMock.SetupGet(s => s.AllowKeyboardLayout).Returns(true);
settingsMock.SetupGet(s => s.AllowWirelessNetwork).Returns(true);
systemInfoMock.SetupGet(s => s.HasBattery).Returns(true);
uiFactoryMock.Setup(u => u.CreateNotification(It.IsAny<INotificationInfo>())).Returns(new Mock<INotificationButton>().Object);
@ -57,6 +60,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
settingsMock.Object,
keyboardLayoutMock.Object,
powerSupplyMock.Object,
wirelessNetworkMock.Object,
systemInfoMock.Object,
taskbarMock.Object,
textMock.Object,
@ -73,7 +77,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
keyboardLayoutMock.Verify(k => k.Initialize(It.IsAny<ISystemKeyboardLayoutControl>()), Times.Once);
powerSupplyMock.Verify(p => p.Initialize(It.IsAny<ISystemPowerSupplyControl>()), Times.Once);
taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(2));
wirelessNetworkMock.Verify(w => w.Initialize(It.IsAny<ISystemWirelessNetworkControl>()), Times.Once);
taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(3));
taskbarMock.Verify(t => t.AddNotification(It.IsAny<INotificationButton>()), Times.Once);
}
@ -84,6 +89,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
keyboardLayoutMock.Verify(k => k.Terminate(), Times.Once);
powerSupplyMock.Verify(p => p.Terminate(), Times.Once);
wirelessNetworkMock.Verify(w => w.Terminate(), Times.Once);
}
}
}

View file

@ -25,6 +25,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
private ITaskbarSettings settings;
private ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout;
private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
private ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork;
private ISystemInfo systemInfo;
private ITaskbar taskbar;
private IUserInterfaceFactory uiFactory;
@ -37,6 +38,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
ITaskbarSettings settings,
ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout,
ISystemComponent<ISystemPowerSupplyControl> powerSupply,
ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork,
ISystemInfo systemInfo,
ITaskbar taskbar,
IText text,
@ -50,6 +52,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
this.taskbar = taskbar;
this.text = text;
this.uiFactory = uiFactory;
this.wirelessNetwork = wirelessNetwork;
}
public void Perform()
@ -71,6 +74,11 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
{
AddPowerSupplyControl();
}
if (settings.AllowWirelessNetwork)
{
AddWirelessNetworkControl();
}
}
public void Revert()
@ -92,6 +100,11 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
{
powerSupply.Terminate();
}
if (settings.AllowWirelessNetwork)
{
wirelessNetwork.Terminate();
}
}
private void AddKeyboardLayoutControl()
@ -110,6 +123,14 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
taskbar.AddSystemControl(control);
}
private void AddWirelessNetworkControl()
{
var control = uiFactory.CreateWirelessNetworkControl();
wirelessNetwork.Initialize(control);
taskbar.AddSystemControl(control);
}
private void CreateLogNotification()
{
var logInfo = new LogNotificationInfo(text);

View file

@ -48,8 +48,12 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="SimpleWifi, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleWifi.1.0.0.0\lib\net40\SimpleWifi.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Management" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
@ -57,6 +61,8 @@
<Compile Include="KeyboardLayout.cs" />
<Compile Include="PowerSupply.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WirelessNetwork.cs" />
<Compile Include="WirelessNetworkDefinition.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj">
@ -64,5 +70,8 @@
<Name>SafeExamBrowser.Contracts</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -0,0 +1,186 @@
/*
* Copyright (c) 2017 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;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Net.NetworkInformation;
using System.Timers;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.SystemComponents;
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
using SimpleWifi;
using SimpleWifi.Win32;
namespace SafeExamBrowser.SystemComponents
{
public class WirelessNetwork : ISystemComponent<ISystemWirelessNetworkControl>
{
private const int TWO_SECONDS = 2000;
private ILogger logger;
private ISystemWirelessNetworkControl control;
private Timer timer;
private Wifi wifi;
public WirelessNetwork(ILogger logger)
{
this.logger = logger;
}
public void Initialize(ISystemWirelessNetworkControl control)
{
this.control = control;
this.wifi = new Wifi();
if (wifi.NoWifiAvailable || IsTurnedOff())
{
control.HasWirelessNetworkAdapter = false;
logger.Info("Wireless networks cannot be monitored, as there is no hardware adapter available or it is turned off.");
}
else
{
control.HasWirelessNetworkAdapter = true;
control.NetworkSelected += Control_NetworkSelected;
wifi.ConnectionStatusChanged += Wifi_ConnectionStatusChanged;
UpdateControl();
timer = new Timer(TWO_SECONDS);
timer.Elapsed += Timer_Elapsed;
timer.AutoReset = true;
timer.Start();
logger.Info("Started monitoring the wireless network adapter.");
}
}
public void Terminate()
{
timer?.Stop();
control?.Close();
if (timer != null)
{
logger.Info("Stopped monitoring the wireless network adapter.");
}
}
private void Control_NetworkSelected(IWirelessNetwork network)
{
throw new NotImplementedException();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
UpdateControl();
}
private void Wifi_ConnectionStatusChanged(object sender, WifiStatusEventArgs e)
{
control.NetworkStatus = ToStatus(e.NewStatus);
}
private bool IsTurnedOff()
{
try
{
// See https://msdn.microsoft.com/en-us/library/aa394216(v=vs.85).aspx
string query = @"
SELECT *
FROM Win32_NetworkAdapter";
var searcher = new ManagementObjectSearcher(query);
var adapters = searcher.Get();
var interfaces = NetworkInterface.GetAllNetworkInterfaces().Where(i => i.NetworkInterfaceType == NetworkInterfaceType.Wireless80211).ToList();
logger.Info("Interface count: " + interfaces.Count);
foreach (var i in interfaces)
{
logger.Info(i.Description);
logger.Info(i.Id);
logger.Info(i.Name);
logger.Info(i.NetworkInterfaceType.ToString());
logger.Info(i.OperationalStatus.ToString());
logger.Info("-----");
}
foreach (var adapter in adapters)
{
logger.Info("-------");
foreach (var property in adapter.Properties)
{
logger.Info($"{property.Name}: {property.Value} ({property.Type})");
}
}
logger.Info("Adapter count: " + adapters.Count);
return true;
using (var client = new WlanClient())
{
foreach (var @interface in client.Interfaces)
{
Trace.WriteLine($"[{@interface.InterfaceName}]");
foreach (var state in @interface.RadioState.PhyRadioState)
{
Trace.WriteLine($"PhyIndex: {state.dwPhyIndex}");
Trace.WriteLine($"SoftwareRadioState: {state.dot11SoftwareRadioState}");
Trace.WriteLine($"HardwareRadioState: {state.dot11HardwareRadioState}");
}
}
}
}
catch (Exception e)
{
logger.Error("Fail!", e);
return true;
}
}
private void UpdateControl()
{
var networks = new List<IWirelessNetwork>();
control.NetworkStatus = ToStatus(wifi.ConnectionStatus);
try
{
foreach (var accessPoint in wifi.GetAccessPoints())
{
// The user may only connect to an already configured wireless network!
if (accessPoint.HasProfile)
{
networks.Add(new WirelessNetworkDefinition
{
Name = accessPoint.Name,
SignalStrength = Convert.ToInt32(accessPoint.SignalStrength),
Status = accessPoint.IsConnected ? WirelessNetworkStatus.Connected : WirelessNetworkStatus.Disconnected
});
}
}
}
catch (Exception e)
{
logger.Error("Failed to update the wireless network adapter status!", e);
}
control.Update(networks);
}
private WirelessNetworkStatus ToStatus(WifiStatus status)
{
return status == WifiStatus.Connected ? WirelessNetworkStatus.Connected : WirelessNetworkStatus.Disconnected;
}
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2017 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;
using SafeExamBrowser.Contracts.SystemComponents;
namespace SafeExamBrowser.SystemComponents
{
internal class WirelessNetworkDefinition : IWirelessNetwork
{
public Guid Id { get; }
public string Name { get; set; }
public int SignalStrength { get; set; }
public WirelessNetworkStatus Status { get; set; }
public WirelessNetworkDefinition()
{
Id = Guid.NewGuid();
}
}
}

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="SimpleWifi" version="1.0.0.0" targetFramework="net452" />
</packages>

View file

@ -33,7 +33,7 @@
</Grid>
</Border>
</Popup>
<Button x:Name="Button" Background="Transparent" Template="{StaticResource TaskbarButton}">
<Button x:Name="Button" Background="Transparent" IsEnabled="False" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True">
<Viewbox Stretch="Uniform" Width="Auto">
<Canvas Height="40" Width="40">
<Viewbox Stretch="Uniform" Width="40" Panel.ZIndex="2">

View file

@ -72,12 +72,14 @@ namespace SafeExamBrowser.UserInterface.Classic.Controls
Popup.IsOpen = true;
PopupText.Text = text;
Background = Brushes.LightGray;
Button.IsEnabled = true;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Popup.IsOpen = false;
Background = Brushes.Transparent;
Button.IsEnabled = false;
}
}
}

View file

@ -0,0 +1,30 @@
<UserControl x:Class="SafeExamBrowser.UserInterface.Classic.Controls.WirelessNetworkButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Classic.Controls"
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Templates/Buttons.xaml" />
<ResourceDictionary Source="../Templates/Colors.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Button x:Name="Button" Height="40" Padding="10,0" Template="{StaticResource TaskbarButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="IsCurrentTextBlock" Grid.Column="0" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden">•</TextBlock>
<TextBlock x:Name="SignalStrengthTextBlock" Grid.Column="1" FontWeight="Bold" HorizontalAlignment="Left" Margin="10,0,5,0" VerticalAlignment="Center" />
<TextBlock x:Name="NetworkNameTextBlock" Grid.Column="2" Foreground="Gray" HorizontalAlignment="Left" Margin="5,0,10,0" VerticalAlignment="Center" />
</Grid>
</Button>
</Grid>
</UserControl>

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2017 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.Windows;
using System.Windows.Controls;
namespace SafeExamBrowser.UserInterface.Classic.Controls
{
public partial class WirelessNetworkButton : UserControl
{
public event RoutedEventHandler Click;
public bool IsCurrent
{
set { IsCurrentTextBlock.Visibility = value ? Visibility.Visible : Visibility.Hidden; }
}
public string NetworkName
{
set { NetworkNameTextBlock.Text = value; }
}
public int SignalStrength
{
set { SignalStrengthTextBlock.Text = $"{value}%"; }
}
public WirelessNetworkButton()
{
InitializeComponent();
Button.Click += (o, args) => Click?.Invoke(o, args);
}
}
}

View file

@ -0,0 +1,32 @@
<UserControl x:Class="SafeExamBrowser.UserInterface.Classic.Controls.WirelessNetworkControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Classic.Controls"
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="40">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Templates/Buttons.xaml" />
<ResourceDictionary Source="../Templates/Colors.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Popup x:Name="Popup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}">
<Border Background="LightGray" BorderBrush="Gray" BorderThickness="0.5,0.5,0.5,0">
<ScrollViewer Background="{StaticResource BackgroundBrush}" MaxHeight="250" VerticalScrollBarVisibility="Auto">
<ScrollViewer.Resources>
<s:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">5</s:Double>
</ScrollViewer.Resources>
<StackPanel x:Name="NetworksStackPanel" />
</ScrollViewer>
</Border>
</Popup>
<Button x:Name="Button" Background="Transparent" HorizontalContentAlignment="Stretch" Template="{StaticResource TaskbarButton}"
ToolTipService.ShowOnDisabled="True" VerticalContentAlignment="Stretch" Width="40" />
<TextBlock x:Name="NetworkStatusIcon" HorizontalAlignment="Right" Padding="6,2" Panel.ZIndex="10" VerticalAlignment="Bottom" />
</Grid>
</UserControl>

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2017 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;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media;
using SafeExamBrowser.Contracts.SystemComponents;
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
namespace SafeExamBrowser.UserInterface.Classic.Controls
{
public partial class WirelessNetworkControl : UserControl, ISystemWirelessNetworkControl
{
public bool HasWirelessNetworkAdapter
{
set
{
Dispatcher.BeginInvoke(new Action(() =>
{
Button.IsEnabled = value;
}));
}
}
public WirelessNetworkStatus NetworkStatus
{
set
{
Dispatcher.BeginInvoke(new Action(() =>
{
NetworkStatusIcon.Text = value == WirelessNetworkStatus.Connected ? "&#10004;" : "&#10060;";
NetworkStatusIcon.Foreground = value == WirelessNetworkStatus.Connected ? Brushes.Green : Brushes.Red;
}));
}
}
public event WirelessNetworkSelectedEventHandler NetworkSelected;
public WirelessNetworkControl()
{
InitializeComponent();
InitializeWirelessNetworkControl();
}
public void Close()
{
Popup.IsOpen = false;
}
public void SetTooltip(string text)
{
Dispatcher.BeginInvoke(new Action(() => Button.ToolTip = text));
}
public void Update(IEnumerable<IWirelessNetwork> networks)
{
Dispatcher.BeginInvoke(new Action(() =>
{
foreach (var network in networks)
{
var button = new WirelessNetworkButton();
var isCurrent = network.Status == WirelessNetworkStatus.Connected;
button.Click += (o, args) =>
{
NetworkSelected?.Invoke(network);
};
button.IsCurrent = isCurrent;
button.NetworkName = network.Name;
button.SignalStrength = network.SignalStrength;
if (isCurrent)
{
NetworkStatus = network.Status;
}
NetworksStackPanel.Children.Add(button);
}
}));
}
private void InitializeWirelessNetworkControl()
{
var originalBrush = Button.Background;
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
Button.MouseLeave += (o, args) => Popup.IsOpen = Popup.IsMouseOver;
Popup.MouseLeave += (o, args) => Popup.IsOpen = IsMouseOver;
Popup.Opened += (o, args) =>
{
Background = Brushes.LightBlue;
Button.Background = Brushes.LightBlue;
};
Popup.Closed += (o, args) =>
{
Background = originalBrush;
Button.Background = originalBrush;
};
}
}
}

View file

@ -93,6 +93,12 @@
<Compile Include="Controls\QuitButton.xaml.cs">
<DependentUpon>QuitButton.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\WirelessNetworkButton.xaml.cs">
<DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\WirelessNetworkControl.xaml.cs">
<DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
</Compile>
<Compile Include="LogWindow.xaml.cs">
<DependentUpon>LogWindow.xaml</DependentUpon>
</Compile>
@ -198,6 +204,14 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Resource>
<Page Include="Controls\WirelessNetworkButton.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\WirelessNetworkControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="LogWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View file

@ -100,6 +100,11 @@ namespace SafeExamBrowser.UserInterface.Classic
return splashScreen;
}
public ISystemWirelessNetworkControl CreateWirelessNetworkControl()
{
return new WirelessNetworkControl();
}
public void Show(string message, string title, MessageBoxAction action = MessageBoxAction.Confirm, MessageBoxIcon icon = MessageBoxIcon.Information)
{
MessageBox.Show(message, title, ToButton(action), ToImage(icon));

View file

@ -101,6 +101,12 @@ namespace SafeExamBrowser.UserInterface.Windows10
return splashScreen;
}
public ISystemWirelessNetworkControl CreateWirelessNetworkControl()
{
// TODO
throw new System.NotImplementedException();
}
public void Show(string message, string title, MessageBoxAction action = MessageBoxAction.Confirm, MessageBoxIcon icon = MessageBoxIcon.Information)
{
MessageBox.Show(message, title, ToButton(action), ToImage(icon));

View file

@ -49,6 +49,7 @@ namespace SafeExamBrowser
private ISettings settings;
private ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout;
private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
private ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork;
private ISystemInfo systemInfo;
private IText text;
private IUserInterfaceFactory uiFactory;
@ -81,6 +82,7 @@ namespace SafeExamBrowser
powerSupply = new PowerSupply(new ModuleLogger(logger, typeof(PowerSupply)), text);
processMonitor = new ProcessMonitor(new ModuleLogger(logger, typeof(ProcessMonitor)), nativeMethods);
windowMonitor = new WindowMonitor(new ModuleLogger(logger, typeof(WindowMonitor)), nativeMethods);
wirelessNetwork = new WirelessNetwork(new ModuleLogger(logger, typeof(WirelessNetwork)));
runtimeController = new RuntimeController(displayMonitor, new ModuleLogger(logger, typeof(RuntimeController)), processMonitor, Taskbar, windowMonitor);
ShutdownController = new ShutdownController(logger, settings, text, uiFactory);
@ -92,7 +94,7 @@ namespace SafeExamBrowser
StartupOperations.Enqueue(new WindowMonitorOperation(logger, windowMonitor));
StartupOperations.Enqueue(new ProcessMonitorOperation(logger, processMonitor));
StartupOperations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, Taskbar));
StartupOperations.Enqueue(new TaskbarOperation(logger, settings.Taskbar, keyboardLayout, powerSupply, systemInfo, Taskbar, text, uiFactory));
StartupOperations.Enqueue(new TaskbarOperation(logger, settings.Taskbar, keyboardLayout, powerSupply, wirelessNetwork, systemInfo, Taskbar, text, uiFactory));
StartupOperations.Enqueue(new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory));
StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, logger));
StartupOperations.Enqueue(new ClipboardOperation(logger, nativeMethods));