Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions CefSharp.OutOfProcess.BrowserProcess/BrowserProcessHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Diagnostics;
using CefSharp.OutOfProcess.Interface;
using System.Threading.Tasks;
using CefSharp.OutOfProcess.BrowserProcess.CallbackProxies;
using CefSharp.OutOfProcess.Interface.Callbacks;

namespace CefSharp.OutOfProcess.BrowserProcess
{
Expand Down Expand Up @@ -38,8 +40,22 @@ protected override void OnContextInitialized()
var threadId = Kernel32.GetCurrentThreadId();

_outOfProcessServer.NotifyContextInitialized(threadId, Cef.CefSharpVersion, Cef.CefVersion, Cef.ChromiumVersion);
_outOfProcessServer.BeforeDownloadCallback += _outOfProcessServer_BeforeDownloadCallback;
_outOfProcessServer.DownloadCallback += _outOfProcessServer_DownloadCallback;
}

private void _outOfProcessServer_DownloadCallback(object sender, DownloadCallbackDetails e)
{
((DownloadHandlerProxy)GetBrowser(e.BrowserId).DownloadHandler)?.DownloadCallback(e);
}

private void _outOfProcessServer_BeforeDownloadCallback(object sender, BeforeDownloadCallbackDetails e)
{
((DownloadHandlerProxy)GetBrowser(e.BrowserId).DownloadHandler)?.BeforeDownloadCallback(e);
}

private OutOfProcessChromiumWebBrowser GetBrowser(int id) => _browsers.FirstOrDefault(x => x.Id == id);

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
Expand Down Expand Up @@ -69,9 +85,7 @@ Task IOutOfProcessClientRpc.SendDevToolsMessage(int browserId, string message)
{
return CefThread.ExecuteOnUiThread(() =>
{
var browser = _browsers.FirstOrDefault(x => x.Id == browserId);

browser?.GetBrowserHost().SendDevToolsMessage(message);
GetBrowser(browserId).GetBrowserHost().SendDevToolsMessage(message);

return true;
});
Expand Down Expand Up @@ -120,9 +134,7 @@ void IOutOfProcessClientRpc.NotifyMoveOrResizeStarted(int browserId)

void IOutOfProcessClientRpc.SetFocus(int browserId, bool focus)
{
var browser = _browsers.FirstOrDefault(x => x.Id == browserId);

browser?.GetBrowserHost().SetFocus(focus);
GetBrowser(browserId).GetBrowserHost().SetFocus(focus);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using CefSharp.OutOfProcess.Interface;

namespace CefSharp.OutOfProcess.BrowserProcess.CallbackProxies
{
internal class CallbackProxyBase<T> : IDisposable
{
private int id = 0;
private readonly Dictionary<int, T> callbacks = new Dictionary<int, T>();
private protected readonly IOutOfProcessHostRpc host;

public CallbackProxyBase(IOutOfProcessHostRpc host)
{
this.host = host ?? throw new ArgumentNullException(nameof(host));
}

protected int CreateCallback(T callback)
{
int lid = id++;
callbacks.Add(lid, callback);
return lid;
}

protected T GetCallback(int id)
{
T cb = callbacks[id];
callbacks.Remove(id);
return cb;
}

public void Dispose()
{
foreach (var cbs in callbacks)
{
if (cbs.Value is IDisposable d)
{
d.Dispose();
}
}

callbacks.Clear();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
namespace CefSharp.OutOfProcess.BrowserProcess.CallbackProxies
{
using System.Diagnostics;
using CefSharp;
using CefSharp.OutOfProcess.Interface;
using CefSharp.OutOfProcess.Interface.Callbacks;

internal class DownloadHandlerProxy : CallbackProxyBase<object>, IDownloadHandler
{
public DownloadHandlerProxy(IOutOfProcessHostRpc host)
: base(host)
{
}

public void BeforeDownloadCallback(BeforeDownloadCallbackDetails details)
{
((CefSharp.OutOfProcess.Interface.Callbacks.IBeforeDownloadCallback)GetCallback(details.CallbackId)).Continue(details.DownloadPath, details.ShowDialog);
}

public void DownloadCallback(DownloadCallbackDetails details)
{
var cb = (CefSharp.OutOfProcess.Interface.Callbacks.IDownloadItemCallback)GetCallback(details.CallbackId);
if (details.Cancel)
{
cb.Cancel();
}
else if (details.Pause)
{
cb.Pause();
}
else if (details.Resume)
{
cb.Resume();
}
}

bool IDownloadHandler.CanDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, string url, string requestMethod)
{
return host.OnCanDownloadAsync(((OutOfProcessChromiumWebBrowser)chromiumWebBrowser).Id, url, requestMethod).Result;
}

void IDownloadHandler.OnBeforeDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, CefSharp.DownloadItem downloadItem, CefSharp.IBeforeDownloadCallback callback)
{
host.OnBeforeDownload(((OutOfProcessChromiumWebBrowser)chromiumWebBrowser).Id, Convert(downloadItem), CreateCallback(callback));
}

void IDownloadHandler.OnDownloadUpdated(IWebBrowser chromiumWebBrowser, IBrowser browser, CefSharp.DownloadItem downloadItem, CefSharp.IDownloadItemCallback callback)
{
host.OnDownloadUpdated(((OutOfProcessChromiumWebBrowser)chromiumWebBrowser).Id, Convert(downloadItem), CreateCallback(callback));
}

private static CefSharp.OutOfProcess.Interface.Callbacks.DownloadItem Convert(CefSharp.DownloadItem item) => new CefSharp.OutOfProcess.Interface.Callbacks.DownloadItem()
{
SuggestedFileName = item.SuggestedFileName,
CurrentSpeed = item.CurrentSpeed,
Id = item.Id,
ContentDisposition = item.ContentDisposition,
EndTime = item.EndTime,
FullPath = item.FullPath,
IsCancelled = item.IsCancelled,
IsComplete = item.IsComplete,
IsInProgress = item.IsInProgress,
IsValid = item.IsValid,
MimeType = item.MimeType,
OriginalUrl = item.OriginalUrl,
PercentComplete = item.PercentComplete,
ReceivedBytes = item.ReceivedBytes,
StartTime = item.StartTime,
TotalBytes = item.TotalBytes,
Url = item.Url,
};
}
}
44 changes: 44 additions & 0 deletions CefSharp.OutOfProcess.Core/CallbackProxies/CallbackProxyBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
namespace CefSharp.OutOfProcess
{
using System;
using CefSharp.OutOfProcess.Internal;

internal class CallbackProxyBase : IDisposable
{
private protected readonly OutOfProcessHost outOfProcessHost;
private protected readonly int callback;
private protected readonly IChromiumWebBrowserInternal chromiumWebBrowser;
private bool disposedValue;

public CallbackProxyBase(OutOfProcessHost outOfProcessHost, int callback, IChromiumWebBrowserInternal chromiumWebBrowser)
{
this.chromiumWebBrowser = chromiumWebBrowser;
this.outOfProcessHost = outOfProcessHost;
this.callback = callback;
}

public bool IsDisposed => disposedValue;

protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects)
}

// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
disposedValue = true;
}
}

void IDisposable.Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
namespace CefSharp.OutOfProcess
{
using CefSharp.OutOfProcess.Interface.Callbacks;
using CefSharp.OutOfProcess.Internal;

internal sealed class DownloadCallbackProxy : CallbackProxyBase, IBeforeDownloadCallback, IDownloadItemCallback
{
public DownloadCallbackProxy(OutOfProcessHost outOfProcessHost, int callback, IChromiumWebBrowserInternal chromiumWebBrowser)
: base(outOfProcessHost, callback, chromiumWebBrowser)
{
}

void IDownloadItemCallback.Cancel()
{
outOfProcessHost.InvokeDownloadCallback(new DownloadCallbackDetails()
{
CallbackId = callback,
BrowserId = chromiumWebBrowser.Id,
Cancel = true,
});
}

void IBeforeDownloadCallback.Continue(string downloadPath, bool showDialog)
{
outOfProcessHost.InvokeBeforeDownloadCallback(new BeforeDownloadCallbackDetails()
{
CallbackId = callback,
BrowserId = chromiumWebBrowser.Id,
DownloadPath = downloadPath,
ShowDialog = showDialog,
});
}

void IDownloadItemCallback.Pause()
{
outOfProcessHost.InvokeDownloadCallback(new DownloadCallbackDetails()
{
CallbackId = callback,
BrowserId = chromiumWebBrowser.Id,
Pause = true,
});
}

void IDownloadItemCallback.Resume()
{
outOfProcessHost.InvokeDownloadCallback(new DownloadCallbackDetails()
{
CallbackId = callback,
BrowserId = chromiumWebBrowser.Id,
Resume = true,
});
}
}
}
5 changes: 3 additions & 2 deletions CefSharp.OutOfProcess.Core/CefSharp.OutOfProcess.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>net462</TargetFramework>
<PlatformTarget>AnyCPU</PlatformTarget>
<RootNamespace>CefSharp.OutOfProcess</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="PInvoke.Kernel32" Version="0.7.104" />
<PackageReference Include="PInvoke.User32" Version="0.7.104" />
<PackageReference Include="StreamJsonRpc" Version="2.11.35" />

<ProjectReference Include="..\CefSharp.OutOfProcess.Interface\CefSharp.OutOfProcess.Interface.csproj" />

<ProjectReference Include="..\CefSharp.Dom\lib\PuppeteerSharp\CefSharp.Dom.OutOfProcess.csproj" />
</ItemGroup>

Expand Down
13 changes: 13 additions & 0 deletions CefSharp.OutOfProcess.Core/Handler/IDownloadHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace CefSharp.OutOfProcess.Handler
{
using CefSharp.OutOfProcess.Interface.Callbacks;

public interface IDownloadHandler
{
bool CanDownload(IChromiumWebBrowser chromiumWebBrowser, string url, string requestMethod);

void OnBeforeDownload(IChromiumWebBrowser chromiumWebBrowser, CefSharp.OutOfProcess.Interface.Callbacks.DownloadItem downloadItem, IBeforeDownloadCallback callback);

void OnDownloadUpdated(IChromiumWebBrowser chromiumWebBrowser, CefSharp.OutOfProcess.Interface.Callbacks.DownloadItem downloadItem, IDownloadItemCallback callback);
}
}
2 changes: 2 additions & 0 deletions CefSharp.OutOfProcess.Core/IChromiumWebBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,5 +203,7 @@ public interface IChromiumWebBrowser : IDisposable
/// the navigation will resolve with the response of the last redirect. If can not go forward, resolves to null.</returns>
/// <param name="options">Navigation parameters.</param>
Task<Response> GoForwardAsync(NavigationOptions options = null);

Handler.IDownloadHandler DownloadHandler { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class OutOfProcessConnectionTransport : IConnectionTransport

public event EventHandler<MessageReceivedEventArgs> MessageReceived;
public event EventHandler<MessageErrorEventArgs> MessageError;
public event EventHandler Disconnected;

public OutOfProcessConnectionTransport(int browserId, OutOfProcessHost outOfProcessHost)
{
Expand Down
Loading