SEBWIN-449: Added WebView2 with scaffolding for remote proctoring UI.

This commit is contained in:
Damian Büchel 2021-02-19 22:03:52 +01:00
parent d3b5df6180
commit 345c5b7b14
19 changed files with 283 additions and 3 deletions

View file

@ -249,7 +249,7 @@ namespace SafeExamBrowser.Client
private IOperation BuildProctoringOperation()
{
var controller = new ProctoringController();
var controller = new ProctoringController(uiFactory);
var operation = new ProctoringOperation(context, logger, controller);
context.ProctoringController = controller;

View file

@ -8,6 +8,7 @@
using SafeExamBrowser.Core.Contracts.OperationModel;
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.Proctoring.Contracts;
@ -18,7 +19,7 @@ namespace SafeExamBrowser.Client.Operations
private readonly ILogger logger;
private readonly IProctoringController controller;
public override event ActionRequiredEventHandler ActionRequired;
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
public override event StatusChangedEventHandler StatusChanged;
public ProctoringOperation(ClientContext context, ILogger logger, IProctoringController controller) : base(context)
@ -29,11 +30,30 @@ namespace SafeExamBrowser.Client.Operations
public override OperationResult Perform()
{
// TODO
Context.Settings.Proctoring.Enabled = true;
if (Context.Settings.Proctoring.Enabled)
{
logger.Info("Initializing proctoring...");
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeProctoring);
controller.Initialize(Context.Settings.Proctoring);
}
return OperationResult.Success;
}
public override OperationResult Revert()
{
if (Context.Settings.Proctoring.Enabled)
{
logger.Info("Terminating proctoring...");
StatusChanged?.Invoke(TextKey.OperationStatus_TerminateProctoring);
controller.Terminate();
}
return OperationResult.Success;
}
}

View file

@ -139,6 +139,8 @@ namespace SafeExamBrowser.I18n.Contracts
OperationStatus_InitializeBrowser,
OperationStatus_InitializeConfiguration,
OperationStatus_InitializeKioskMode,
// TODO
OperationStatus_InitializeProctoring,
OperationStatus_InitializeRuntimeConnection,
OperationStatus_InitializeServer,
OperationStatus_InitializeServiceSession,
@ -158,6 +160,8 @@ namespace SafeExamBrowser.I18n.Contracts
OperationStatus_StopKeyboardInterception,
OperationStatus_StopMouseInterception,
OperationStatus_TerminateBrowser,
// TODO
OperationStatus_TerminateProctoring,
OperationStatus_TerminateShell,
OperationStatus_ValidateRemoteSessionPolicy,
OperationStatus_ValidateVirtualMachinePolicy,

View file

@ -227,8 +227,9 @@ namespace SafeExamBrowser.Monitoring.Applications
{
var isRuntime = process.Name == "SafeExamBrowser.exe" && process.OriginalName == "SafeExamBrowser.exe";
var isClient = process.Name == "SafeExamBrowser.Client.exe" && process.OriginalName == "SafeExamBrowser.Client.exe";
var isWebView = process.Name == "msedgewebview2.exe" && process.OriginalName == "msedgewebview2.exe";
return isRuntime || isClient;
return isRuntime || isClient || isWebView;
}
private void Close(Window window)

View file

@ -6,6 +6,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using SafeExamBrowser.Settings.Proctoring;
namespace SafeExamBrowser.Proctoring.Contracts
{
/// <summary>
@ -13,6 +15,14 @@ namespace SafeExamBrowser.Proctoring.Contracts
/// </summary>
public interface IProctoringController
{
/// <summary>
///
/// </summary>
void Initialize(ProctoringSettings settings);
/// <summary>
///
/// </summary>
void Terminate();
}
}

View file

@ -57,5 +57,11 @@
<Compile Include="IProctoringController.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Settings\SafeExamBrowser.Settings.csproj">
<Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project>
<Name>SafeExamBrowser.Settings</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2021 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 Microsoft.Web.WebView2.Wpf;
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
namespace SafeExamBrowser.Proctoring
{
internal class ProctoringControl : WebView2, IProctoringControl
{
internal ProctoringControl()
{
Source = new Uri("https://www.microsoft.com");
}
}
}

View file

@ -7,11 +7,34 @@
*/
using SafeExamBrowser.Proctoring.Contracts;
using SafeExamBrowser.Settings.Proctoring;
using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
namespace SafeExamBrowser.Proctoring
{
public class ProctoringController : IProctoringController
{
private readonly IUserInterfaceFactory uiFactory;
private IProctoringWindow window;
public ProctoringController(IUserInterfaceFactory uiFactory)
{
this.uiFactory = uiFactory;
}
public void Initialize(ProctoringSettings settings)
{
var control = new ProctoringControl();
window = uiFactory.CreateProctoringWindow(control);
window.Show();
}
public void Terminate()
{
window?.Close();
}
}
}

View file

@ -12,6 +12,8 @@
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
@ -50,10 +52,24 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Web.WebView2.Core, Version=1.0.705.50, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.WebView2.1.0.705.50\lib\net45\Microsoft.Web.WebView2.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.WebView2.WinForms, Version=1.0.705.50, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.WebView2.1.0.705.50\lib\net45\Microsoft.Web.WebView2.WinForms.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.WebView2.Wpf, Version=1.0.705.50, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.WebView2.1.0.705.50\lib\net45\Microsoft.Web.WebView2.Wpf.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Xaml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="ProctoringControl.cs" />
<Compile Include="ProctoringController.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
@ -66,6 +82,24 @@
<Project>{8e52bd1c-0540-4f16-b181-6665d43f7a7b}</Project>
<Name>SafeExamBrowser.Proctoring.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Settings\SafeExamBrowser.Settings.csproj">
<Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project>
<Name>SafeExamBrowser.Settings</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.UserInterface.Contracts\SafeExamBrowser.UserInterface.Contracts.csproj">
<Project>{c7889e97-6ff6-4a58-b7cb-521ed276b316}</Project>
<Name>SafeExamBrowser.UserInterface.Contracts</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Web.WebView2.1.0.705.50\build\Microsoft.Web.WebView2.targets" Condition="Exists('..\packages\Microsoft.Web.WebView2.1.0.705.50\build\Microsoft.Web.WebView2.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.705.50\build\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.705.50\build\Microsoft.Web.WebView2.targets'))" />
</Target>
</Project>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Web.WebView2" version="1.0.705.50" targetFramework="net472" />
</packages>

View file

@ -19,6 +19,7 @@ using SafeExamBrowser.SystemComponents.Contracts.Keyboard;
using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts.Browser;
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
using SafeExamBrowser.UserInterface.Contracts.Shell;
using SafeExamBrowser.UserInterface.Contracts.Windows;
using SafeExamBrowser.UserInterface.Contracts.Windows.Data;
@ -95,6 +96,11 @@ namespace SafeExamBrowser.UserInterface.Contracts
/// </summary>
ISystemControl CreatePowerSupplyControl(IPowerSupply powerSupply, Location location);
/// <summary>
/// Creates a new proctoring window loaded with the given proctoring control.
/// </summary>
IProctoringWindow CreateProctoringWindow(IProctoringControl control);
/// <summary>
/// Creates a new runtime window which runs on its own thread.
/// </summary>

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2021 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.UserInterface.Contracts.Proctoring
{
/// <summary>
///
/// </summary>
public interface IProctoringControl
{
}
}

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2021 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.UserInterface.Contracts.Windows;
namespace SafeExamBrowser.UserInterface.Contracts.Proctoring
{
/// <summary>
///
/// </summary>
public interface IProctoringWindow : IWindow
{
}
}

View file

@ -67,6 +67,8 @@
<Compile Include="FileSystemDialog\FileSystemElement.cs" />
<Compile Include="FileSystemDialog\FileSystemOperation.cs" />
<Compile Include="FileSystemDialog\IFileSystemDialog.cs" />
<Compile Include="Proctoring\IProctoringControl.cs" />
<Compile Include="Proctoring\IProctoringWindow.cs" />
<Compile Include="IProgressIndicator.cs" />
<Compile Include="IUserInterfaceFactory.cs" />
<Compile Include="MessageBox\IMessageBox.cs" />

View file

@ -165,6 +165,9 @@
<Compile Include="Windows\PasswordDialog.xaml.cs">
<DependentUpon>PasswordDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Windows\ProctoringWindow.xaml.cs">
<DependentUpon>ProctoringWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Windows\RuntimeWindow.xaml.cs">
<DependentUpon>RuntimeWindow.xaml</DependentUpon>
</Compile>
@ -350,6 +353,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Windows\ProctoringWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Windows\ServerFailureDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View file

@ -24,6 +24,7 @@ using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.Browser;
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
using SafeExamBrowser.UserInterface.Contracts.Shell;
using SafeExamBrowser.UserInterface.Contracts.Windows;
using SafeExamBrowser.UserInterface.Contracts.Windows.Data;
@ -162,6 +163,11 @@ namespace SafeExamBrowser.UserInterface.Desktop
}
}
public IProctoringWindow CreateProctoringWindow(IProctoringControl control)
{
return Application.Current.Dispatcher.Invoke(() => new ProctoringWindow(control));
}
public IRuntimeWindow CreateRuntimeWindow(AppConfig appConfig)
{
return Application.Current.Dispatcher.Invoke(() => new RuntimeWindow(appConfig, text));

View file

@ -0,0 +1,10 @@
<Window x:Class="SafeExamBrowser.UserInterface.Desktop.Windows.ProctoringWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Windows"
mc:Ignorable="d"
Title="ProctoringWindow" Height="450" Width="800">
<DockPanel Name="ControlContainer" />
</Window>

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2021 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.ComponentModel;
using System.Windows;
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
using SafeExamBrowser.UserInterface.Contracts.Windows;
using SafeExamBrowser.UserInterface.Contracts.Windows.Events;
namespace SafeExamBrowser.UserInterface.Desktop.Windows
{
public partial class ProctoringWindow : Window, IProctoringWindow
{
private WindowClosingEventHandler closing;
event WindowClosingEventHandler IWindow.Closing
{
add { closing += value; }
remove { closing -= value; }
}
public ProctoringWindow(IProctoringControl control)
{
InitializeComponent();
InitializeWindow(control);
}
public void BringToForeground()
{
Dispatcher.Invoke(() =>
{
if (WindowState == WindowState.Minimized)
{
WindowState = WindowState.Normal;
}
Activate();
});
}
public new void Close()
{
Dispatcher.Invoke(() =>
{
closing?.Invoke();
base.Close();
});
}
public new void Hide()
{
Dispatcher.Invoke(base.Hide);
}
public new void Show()
{
Dispatcher.Invoke(base.Show);
}
private void ProctoringWindow_Closing(object sender, CancelEventArgs e)
{
closing?.Invoke();
}
private void InitializeWindow(object control)
{
if (control is UIElement element)
{
ControlContainer.Children.Add(element);
}
Closing += ProctoringWindow_Closing;
}
}
}

View file

@ -24,6 +24,7 @@ using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
using SafeExamBrowser.SystemComponents.Contracts.WirelessNetwork;
using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.Browser;
using SafeExamBrowser.UserInterface.Contracts.Proctoring;
using SafeExamBrowser.UserInterface.Contracts.Shell;
using SafeExamBrowser.UserInterface.Contracts.Windows;
using SafeExamBrowser.UserInterface.Contracts.Windows.Data;
@ -162,6 +163,12 @@ namespace SafeExamBrowser.UserInterface.Mobile
}
}
public IProctoringWindow CreateProctoringWindow(IProctoringControl control)
{
// TODO
throw new System.NotImplementedException();
}
public IRuntimeWindow CreateRuntimeWindow(AppConfig appConfig)
{
return Application.Current.Dispatcher.Invoke(() => new RuntimeWindow(appConfig, text));