SEBWIN-531, #240: Refactored browser application instance to browser window.
This commit is contained in:
parent
fa3763a32a
commit
83c387cffd
4 changed files with 70 additions and 65 deletions
|
@ -37,12 +37,11 @@ namespace SafeExamBrowser.Browser
|
||||||
{
|
{
|
||||||
public class BrowserApplication : IBrowserApplication
|
public class BrowserApplication : IBrowserApplication
|
||||||
{
|
{
|
||||||
private int instanceIdCounter = default(int);
|
private int windowIdCounter = default;
|
||||||
|
|
||||||
private readonly AppConfig appConfig;
|
private readonly AppConfig appConfig;
|
||||||
private readonly IFileSystemDialog fileSystemDialog;
|
private readonly IFileSystemDialog fileSystemDialog;
|
||||||
private readonly IHashAlgorithm hashAlgorithm;
|
private readonly IHashAlgorithm hashAlgorithm;
|
||||||
private readonly List<BrowserApplicationInstance> instances;
|
|
||||||
private readonly IKeyGenerator keyGenerator;
|
private readonly IKeyGenerator keyGenerator;
|
||||||
private readonly IModuleLogger logger;
|
private readonly IModuleLogger logger;
|
||||||
private readonly IMessageBox messageBox;
|
private readonly IMessageBox messageBox;
|
||||||
|
@ -50,6 +49,7 @@ namespace SafeExamBrowser.Browser
|
||||||
private readonly BrowserSettings settings;
|
private readonly BrowserSettings settings;
|
||||||
private readonly IText text;
|
private readonly IText text;
|
||||||
private readonly IUserInterfaceFactory uiFactory;
|
private readonly IUserInterfaceFactory uiFactory;
|
||||||
|
private readonly List<BrowserWindow> windows;
|
||||||
|
|
||||||
public bool AutoStart { get; private set; }
|
public bool AutoStart { get; private set; }
|
||||||
public IconResource Icon { get; private set; }
|
public IconResource Icon { get; private set; }
|
||||||
|
@ -77,7 +77,6 @@ namespace SafeExamBrowser.Browser
|
||||||
this.appConfig = appConfig;
|
this.appConfig = appConfig;
|
||||||
this.fileSystemDialog = fileSystemDialog;
|
this.fileSystemDialog = fileSystemDialog;
|
||||||
this.hashAlgorithm = hashAlgorithm;
|
this.hashAlgorithm = hashAlgorithm;
|
||||||
this.instances = new List<BrowserApplicationInstance>();
|
|
||||||
this.keyGenerator = keyGenerator;
|
this.keyGenerator = keyGenerator;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.messageBox = messageBox;
|
this.messageBox = messageBox;
|
||||||
|
@ -85,11 +84,12 @@ namespace SafeExamBrowser.Browser
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.uiFactory = uiFactory;
|
this.uiFactory = uiFactory;
|
||||||
|
this.windows = new List<BrowserWindow>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IApplicationWindow> GetWindows()
|
public IEnumerable<IApplicationWindow> GetWindows()
|
||||||
{
|
{
|
||||||
return new List<IApplicationWindow>(instances);
|
return new List<IApplicationWindow>(windows);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
|
@ -123,7 +123,7 @@ namespace SafeExamBrowser.Browser
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
CreateNewInstance();
|
CreateNewWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Terminate()
|
public void Terminate()
|
||||||
|
@ -131,11 +131,11 @@ namespace SafeExamBrowser.Browser
|
||||||
logger.Info("Initiating termination...");
|
logger.Info("Initiating termination...");
|
||||||
AwaitReady();
|
AwaitReady();
|
||||||
|
|
||||||
foreach (var instance in instances)
|
foreach (var window in windows)
|
||||||
{
|
{
|
||||||
instance.Terminated -= Instance_Terminated;
|
window.Closed -= Window_Closed;
|
||||||
instance.Terminate();
|
window.Close();
|
||||||
logger.Info($"Terminated browser instance {instance.Id}.");
|
logger.Info($"Closed browser window #{window.Id}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.UseTemporaryDownAndUploadDirectory)
|
if (settings.UseTemporaryDownAndUploadDirectory)
|
||||||
|
@ -170,37 +170,37 @@ namespace SafeExamBrowser.Browser
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateNewInstance(string url = null)
|
private void CreateNewWindow(string url = null)
|
||||||
{
|
{
|
||||||
var id = ++instanceIdCounter;
|
var id = ++windowIdCounter;
|
||||||
var isMainInstance = instances.Count == 0;
|
var isMainWindow = windows.Count == 0;
|
||||||
var instanceLogger = logger.CloneFor($"Browser Instance #{id}");
|
|
||||||
var startUrl = url ?? GenerateStartUrl();
|
var startUrl = url ?? GenerateStartUrl();
|
||||||
var instance = new BrowserApplicationInstance(
|
var windowLogger = logger.CloneFor($"Browser Window #{id}");
|
||||||
|
var window = new BrowserWindow(
|
||||||
appConfig,
|
appConfig,
|
||||||
settings,
|
settings,
|
||||||
id,
|
id,
|
||||||
isMainInstance,
|
isMainWindow,
|
||||||
fileSystemDialog,
|
fileSystemDialog,
|
||||||
hashAlgorithm,
|
hashAlgorithm,
|
||||||
keyGenerator,
|
keyGenerator,
|
||||||
messageBox,
|
messageBox,
|
||||||
instanceLogger,
|
windowLogger,
|
||||||
text,
|
text,
|
||||||
uiFactory,
|
uiFactory,
|
||||||
startUrl);
|
startUrl);
|
||||||
|
|
||||||
instance.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args);
|
window.Closed += Window_Closed;
|
||||||
instance.PopupRequested += Instance_PopupRequested;
|
window.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args);
|
||||||
instance.ResetRequested += Instance_ResetRequested;
|
window.PopupRequested += Window_PopupRequested;
|
||||||
instance.SessionIdentifierDetected += (i) => SessionIdentifierDetected?.Invoke(i);
|
window.ResetRequested += Window_ResetRequested;
|
||||||
instance.Terminated += Instance_Terminated;
|
window.SessionIdentifierDetected += (i) => SessionIdentifierDetected?.Invoke(i);
|
||||||
instance.TerminationRequested += () => TerminationRequested?.Invoke();
|
window.TerminationRequested += () => TerminationRequested?.Invoke();
|
||||||
|
|
||||||
instance.Initialize();
|
window.Initialize();
|
||||||
instances.Add(instance);
|
windows.Add(window);
|
||||||
|
|
||||||
logger.Info($"Created browser instance {instance.Id}.");
|
logger.Info($"Created browser window #{window.Id}.");
|
||||||
WindowsChanged?.Invoke();
|
WindowsChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,25 +412,32 @@ namespace SafeExamBrowser.Browser
|
||||||
throw new NotImplementedException($"Mapping for proxy protocol '{protocol}' is not yet implemented!");
|
throw new NotImplementedException($"Mapping for proxy protocol '{protocol}' is not yet implemented!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Instance_PopupRequested(PopupRequestedEventArgs args)
|
private void Window_Closed(int id)
|
||||||
{
|
{
|
||||||
logger.Info($"Received request to create new instance{(settings.AdditionalWindow.UrlPolicy.CanLog() ? $" for '{args.Url}'" : "")}...");
|
windows.Remove(windows.First(i => i.Id == id));
|
||||||
CreateNewInstance(args.Url);
|
WindowsChanged?.Invoke();
|
||||||
|
logger.Info($"Window #{id} has been closed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Instance_ResetRequested()
|
private void Window_PopupRequested(PopupRequestedEventArgs args)
|
||||||
|
{
|
||||||
|
logger.Info($"Received request to create new window{(settings.AdditionalWindow.UrlPolicy.CanLog() ? $" for '{args.Url}'" : "")}...");
|
||||||
|
CreateNewWindow(args.Url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Window_ResetRequested()
|
||||||
{
|
{
|
||||||
logger.Info("Attempting to reset browser...");
|
logger.Info("Attempting to reset browser...");
|
||||||
AwaitReady();
|
AwaitReady();
|
||||||
|
|
||||||
foreach (var instance in instances)
|
foreach (var window in windows)
|
||||||
{
|
{
|
||||||
instance.Terminated -= Instance_Terminated;
|
window.Closed -= Window_Closed;
|
||||||
instance.Terminate();
|
window.Close();
|
||||||
logger.Info($"Terminated browser instance {instance.Id}.");
|
logger.Info($"Closed browser window #{window.Id}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
instances.Clear();
|
windows.Clear();
|
||||||
WindowsChanged?.Invoke();
|
WindowsChanged?.Invoke();
|
||||||
|
|
||||||
if (settings.DeleteCookiesOnStartup && settings.DeleteCookiesOnShutdown)
|
if (settings.DeleteCookiesOnStartup && settings.DeleteCookiesOnShutdown)
|
||||||
|
@ -439,14 +446,8 @@ namespace SafeExamBrowser.Browser
|
||||||
}
|
}
|
||||||
|
|
||||||
nativeMethods.EmptyClipboard();
|
nativeMethods.EmptyClipboard();
|
||||||
CreateNewInstance();
|
CreateNewWindow();
|
||||||
logger.Info("Successfully reset browser.");
|
logger.Info("Successfully reset browser.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Instance_Terminated(int id)
|
|
||||||
{
|
|
||||||
instances.Remove(instances.First(i => i.Id == id));
|
|
||||||
WindowsChanged?.Invoke();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ using TitleChangedEventHandler = SafeExamBrowser.Applications.Contracts.Events.T
|
||||||
|
|
||||||
namespace SafeExamBrowser.Browser
|
namespace SafeExamBrowser.Browser
|
||||||
{
|
{
|
||||||
internal class BrowserApplicationInstance : IApplicationWindow
|
internal class BrowserWindow : IApplicationWindow
|
||||||
{
|
{
|
||||||
private const double ZOOM_FACTOR = 0.2;
|
private const double ZOOM_FACTOR = 0.2;
|
||||||
|
|
||||||
|
@ -45,22 +45,22 @@ namespace SafeExamBrowser.Browser
|
||||||
private readonly IFileSystemDialog fileSystemDialog;
|
private readonly IFileSystemDialog fileSystemDialog;
|
||||||
private readonly IHashAlgorithm hashAlgorithm;
|
private readonly IHashAlgorithm hashAlgorithm;
|
||||||
private readonly HttpClient httpClient;
|
private readonly HttpClient httpClient;
|
||||||
|
private readonly bool isMainWindow;
|
||||||
private readonly IKeyGenerator keyGenerator;
|
private readonly IKeyGenerator keyGenerator;
|
||||||
private readonly IModuleLogger logger;
|
private readonly IModuleLogger logger;
|
||||||
private readonly IMessageBox messageBox;
|
private readonly IMessageBox messageBox;
|
||||||
|
private readonly BrowserSettings settings;
|
||||||
|
private readonly string startUrl;
|
||||||
private readonly IText text;
|
private readonly IText text;
|
||||||
private readonly IUserInterfaceFactory uiFactory;
|
private readonly IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
private IBrowserControl control;
|
private IBrowserControl control;
|
||||||
private IBrowserWindow window;
|
private IBrowserWindow window;
|
||||||
private bool isMainInstance;
|
|
||||||
private BrowserSettings settings;
|
|
||||||
private string startUrl;
|
|
||||||
private double zoomLevel;
|
private double zoomLevel;
|
||||||
|
|
||||||
private WindowSettings WindowSettings
|
private WindowSettings WindowSettings
|
||||||
{
|
{
|
||||||
get { return isMainInstance ? settings.MainWindow : settings.AdditionalWindow; }
|
get { return isMainWindow ? settings.MainWindow : settings.AdditionalWindow; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal int Id { get; }
|
internal int Id { get; }
|
||||||
|
@ -69,21 +69,21 @@ namespace SafeExamBrowser.Browser
|
||||||
public IconResource Icon { get; private set; }
|
public IconResource Icon { get; private set; }
|
||||||
public string Title { get; private set; }
|
public string Title { get; private set; }
|
||||||
|
|
||||||
|
internal event WindowClosedEventHandler Closed;
|
||||||
internal event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
internal event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
||||||
internal event PopupRequestedEventHandler PopupRequested;
|
internal event PopupRequestedEventHandler PopupRequested;
|
||||||
internal event ResetRequestedEventHandler ResetRequested;
|
internal event ResetRequestedEventHandler ResetRequested;
|
||||||
internal event SessionIdentifierDetectedEventHandler SessionIdentifierDetected;
|
internal event SessionIdentifierDetectedEventHandler SessionIdentifierDetected;
|
||||||
internal event InstanceTerminatedEventHandler Terminated;
|
|
||||||
internal event TerminationRequestedEventHandler TerminationRequested;
|
internal event TerminationRequestedEventHandler TerminationRequested;
|
||||||
|
|
||||||
public event IconChangedEventHandler IconChanged;
|
public event IconChangedEventHandler IconChanged;
|
||||||
public event TitleChangedEventHandler TitleChanged;
|
public event TitleChangedEventHandler TitleChanged;
|
||||||
|
|
||||||
public BrowserApplicationInstance(
|
public BrowserWindow(
|
||||||
AppConfig appConfig,
|
AppConfig appConfig,
|
||||||
BrowserSettings settings,
|
BrowserSettings settings,
|
||||||
int id,
|
int id,
|
||||||
bool isMainInstance,
|
bool isMainWindow,
|
||||||
IFileSystemDialog fileSystemDialog,
|
IFileSystemDialog fileSystemDialog,
|
||||||
IHashAlgorithm hashAlgorithm,
|
IHashAlgorithm hashAlgorithm,
|
||||||
IKeyGenerator keyGenerator,
|
IKeyGenerator keyGenerator,
|
||||||
|
@ -96,7 +96,7 @@ namespace SafeExamBrowser.Browser
|
||||||
this.appConfig = appConfig;
|
this.appConfig = appConfig;
|
||||||
this.Id = id;
|
this.Id = id;
|
||||||
this.httpClient = new HttpClient();
|
this.httpClient = new HttpClient();
|
||||||
this.isMainInstance = isMainInstance;
|
this.isMainWindow = isMainWindow;
|
||||||
this.fileSystemDialog = fileSystemDialog;
|
this.fileSystemDialog = fileSystemDialog;
|
||||||
this.hashAlgorithm = hashAlgorithm;
|
this.hashAlgorithm = hashAlgorithm;
|
||||||
this.keyGenerator = keyGenerator;
|
this.keyGenerator = keyGenerator;
|
||||||
|
@ -113,18 +113,18 @@ namespace SafeExamBrowser.Browser
|
||||||
window.BringToForeground();
|
window.BringToForeground();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void Close()
|
||||||
|
{
|
||||||
|
window.Close();
|
||||||
|
control.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
internal void Initialize()
|
internal void Initialize()
|
||||||
{
|
{
|
||||||
InitializeControl();
|
InitializeControl();
|
||||||
InitializeWindow();
|
InitializeWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Terminate()
|
|
||||||
{
|
|
||||||
window.Close();
|
|
||||||
control.Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeControl()
|
private void InitializeControl()
|
||||||
{
|
{
|
||||||
var contextMenuHandler = new ContextMenuHandler();
|
var contextMenuHandler = new ContextMenuHandler();
|
||||||
|
@ -210,10 +210,10 @@ namespace SafeExamBrowser.Browser
|
||||||
|
|
||||||
private void InitializeWindow()
|
private void InitializeWindow()
|
||||||
{
|
{
|
||||||
window = uiFactory.CreateBrowserWindow(control, settings, isMainInstance);
|
window = uiFactory.CreateBrowserWindow(control, settings, isMainWindow);
|
||||||
window.Closing += Window_Closing;
|
|
||||||
window.AddressChanged += Window_AddressChanged;
|
window.AddressChanged += Window_AddressChanged;
|
||||||
window.BackwardNavigationRequested += Window_BackwardNavigationRequested;
|
window.BackwardNavigationRequested += Window_BackwardNavigationRequested;
|
||||||
|
window.Closing += Window_Closing;
|
||||||
window.DeveloperConsoleRequested += Window_DeveloperConsoleRequested;
|
window.DeveloperConsoleRequested += Window_DeveloperConsoleRequested;
|
||||||
window.FindRequested += Window_FindRequested;
|
window.FindRequested += Window_FindRequested;
|
||||||
window.ForwardNavigationRequested += Window_ForwardNavigationRequested;
|
window.ForwardNavigationRequested += Window_ForwardNavigationRequested;
|
||||||
|
@ -297,9 +297,13 @@ namespace SafeExamBrowser.Browser
|
||||||
{
|
{
|
||||||
initialPath = args.InitialPath;
|
initialPath = args.InitialPath;
|
||||||
}
|
}
|
||||||
|
else if (string.IsNullOrEmpty(settings.DownAndUploadDirectory))
|
||||||
|
{
|
||||||
|
initialPath = KnownFolders.Downloads.ExpandedPath;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
initialPath = string.IsNullOrEmpty(settings.DownAndUploadDirectory) ? KnownFolders.Downloads.ExpandedPath : Environment.ExpandEnvironmentVariables(settings.DownAndUploadDirectory);
|
initialPath = Environment.ExpandEnvironmentVariables(settings.DownAndUploadDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAllowed)
|
if (isAllowed)
|
||||||
|
@ -382,7 +386,7 @@ namespace SafeExamBrowser.Browser
|
||||||
|
|
||||||
private void HomeNavigationRequested()
|
private void HomeNavigationRequested()
|
||||||
{
|
{
|
||||||
if (isMainInstance && (settings.UseStartUrlAsHomeUrl || !string.IsNullOrWhiteSpace(settings.HomeUrl)))
|
if (isMainWindow && (settings.UseStartUrlAsHomeUrl || !string.IsNullOrWhiteSpace(settings.HomeUrl)))
|
||||||
{
|
{
|
||||||
var navigate = false;
|
var navigate = false;
|
||||||
var url = settings.UseStartUrlAsHomeUrl ? settings.StartUrl : settings.HomeUrl;
|
var url = settings.UseStartUrlAsHomeUrl ? settings.StartUrl : settings.HomeUrl;
|
||||||
|
@ -568,9 +572,9 @@ namespace SafeExamBrowser.Browser
|
||||||
|
|
||||||
private void Window_Closing()
|
private void Window_Closing()
|
||||||
{
|
{
|
||||||
logger.Info($"Instance has terminated.");
|
logger.Info($"Window is closing...");
|
||||||
control.Destroy();
|
control.Destroy();
|
||||||
Terminated?.Invoke(Id);
|
Closed?.Invoke(Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_DeveloperConsoleRequested()
|
private void Window_DeveloperConsoleRequested()
|
|
@ -8,5 +8,5 @@
|
||||||
|
|
||||||
namespace SafeExamBrowser.Browser.Events
|
namespace SafeExamBrowser.Browser.Events
|
||||||
{
|
{
|
||||||
internal delegate void InstanceTerminatedEventHandler(int id);
|
internal delegate void WindowClosedEventHandler(int id);
|
||||||
}
|
}
|
|
@ -79,12 +79,12 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="BrowserApplication.cs" />
|
<Compile Include="BrowserApplication.cs" />
|
||||||
<Compile Include="BrowserApplicationInstance.cs" />
|
<Compile Include="BrowserWindow.cs" />
|
||||||
<Compile Include="Events\DialogRequestedEventArgs.cs" />
|
<Compile Include="Events\DialogRequestedEventArgs.cs" />
|
||||||
<Compile Include="Events\DialogRequestedEventHandler.cs" />
|
<Compile Include="Events\DialogRequestedEventHandler.cs" />
|
||||||
<Compile Include="Events\DownloadUpdatedEventHandler.cs" />
|
<Compile Include="Events\DownloadUpdatedEventHandler.cs" />
|
||||||
<Compile Include="Events\FaviconChangedEventHandler.cs" />
|
<Compile Include="Events\FaviconChangedEventHandler.cs" />
|
||||||
<Compile Include="Events\InstanceTerminatedEventHandler.cs" />
|
<Compile Include="Events\WindowClosedEventHandler.cs" />
|
||||||
<Compile Include="Events\PopupRequestedEventArgs.cs" />
|
<Compile Include="Events\PopupRequestedEventArgs.cs" />
|
||||||
<Compile Include="Events\PopupRequestedEventHandler.cs" />
|
<Compile Include="Events\PopupRequestedEventHandler.cs" />
|
||||||
<Compile Include="Events\ProgressChangedEventHandler.cs" />
|
<Compile Include="Events\ProgressChangedEventHandler.cs" />
|
||||||
|
|
Loading…
Reference in a new issue