OnBeforePluginLoad is implemented by CefRequestContextHandler.
You need to derive a class from CefRequestContextHandler, and instantiate it in your client handler GetRequestContext.
Something like this:
// declaration in client_handler.h
- Code: Select all
class ClientHandler
: public CefClient
...
, public CefRequestContextHandler
{
...
critical_section_t _csSharedRequestContext; // protection for m_SharedRequestContext
CefRefPtr<CefRequestContext> m_SharedRequestContext;
...
public:
CefRefPtr<CefRequestContext> GetRequestContext(
ClientHandler* client_handler);
void CloseRequestContext();
...
};
Browser creation:
- Code: Select all
... function to create a CefBrowser
return CefBrowserHost::CreateBrowser(
info,
static_cast<CefRefPtr<CefClient>>(m_Handler),
url, settings,
GetRequestContext( pClientHandler ) // <== here we create (the "de facto" singleton) context and pass client handler to our ClientRequestContextHandler implementation
);
// client handler GetRequestContext implementation
- Code: Select all
CefRefPtr<CefRequestContext> ClientHandler::GetRequestContext(
ClientHandler* client_handler)
{
DCHECK(CefCurrentlyOn(TID_UI));
...
// all browsers are sharing the same request context (for now)
critical_section_lock_t lock(&_csSharedRequestContext);
if(m_SharedRequestContext.get() == nullptr)
{
m_SharedRequestContext =
CefRequestContext::CreateContext(
CefRequestContext::GetGlobalContext(),
new ClientRequestContextHandler(this)
);
}
DCHECK(m_SharedRequestContext.get());
return m_SharedRequestContext;
}
void ClientHandler::CloseRequestContext() // call this on shutdown - lifetime it's up to you
{
critical_section_lock_t lock(&_csSharedRequestContext);
m_SharedRequestContext = nullptr;
}
ClientRequestContextHandler implementation:
- Code: Select all
class ClientRequestContextHandler
: public CefRequestContextHandler {
private:
ClientHandler* m_handler; // weak ref
public:
ClientRequestContextHandler(ClientHandler* handler)
: m_handler(handler)
{}
~ClientRequestContextHandler()
{
m_handler = nullptr;
}
public:
CefRefPtr<CefCookieManager> GetCookieManager() override {
return NULL;
}
bool OnBeforePluginLoad(const CefString& mime_type,
const CefString& plugin_url, bool is_main_frame,
const CefString& top_origin_url,
CefRefPtr<CefWebPluginInfo> plugin_info,
PluginPolicy* plugin_policy) override {
// simply forward it to client handler
if(m_handler) {
if(m_handler->OnBeforePluginLoad(mime_type,
plugin_url, is_main_frame, top_origin_url,
plugin_info, plugin_policy)) {
// handled by client handler
return true;
}
}
return __super::OnBeforePluginLoad(mime_type,
plugin_url, is_main_frame, top_origin_url,
plugin_info, plugin_policy);
}
void OnUnloadablePlugin(const CefString& url,
const CefString& mime_type) override
{
if(m_handler) {
m_handler->OnUnloadablePlugin(url, mime_type);
}
}
private:
IMPLEMENT_REFCOUNTING(ClientRequestContextHandler);
};
And finally the proxied implementation in client handler (trimmed of sample):
- Code: Select all
bool ClientHandler::OnBeforePluginLoad(
const CefString& mime_type,
const CefString& plugin_url,
bool is_main_frame,
const CefString& policy_url,
CefRefPtr<CefWebPluginInfo> info,
CefRequestContextHandler::PluginPolicy* plugin_policy)
{
METHOD_GUARD_(CefRequestHandler, OnBeforePluginLoad, false)
if(plugin_policy == nullptr)
return false;
const char* kFlashMimeType = "application/x-shockwave-flash";
if(info.get()) {
CefRefPtr<CefListValue> mime_types = info->GetMimeTypes();
if(mime_types.get() != 0) {
size_t cMimeTypes = mime_types->GetSize();
for(size_t c = 0; c < cMimeTypes; c++)
{
CefString sMimeType = mime_types->GetString(c);
if(sMimeType == kFlashMimeType) {
*plugin_policy = PLUGIN_POLICY_ALLOW;
return true; // explicitely allowed by us
}
}
}
}
...
return false; // no verdict from us, let the default behavior flow
}