in libcef_dll/wrapper/cef_message_router.cc [237:318]
bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) override {
CEF_REQUIRE_UI_THREAD();
const std::string& message_name = message->GetName();
if (message_name == query_message_name_) {
CefRefPtr<CefListValue> args = message->GetArgumentList();
DCHECK_EQ(args->GetSize(), 4U);
const int context_id = args->GetInt(0);
const int request_id = args->GetInt(1);
const CefString& request = args->GetString(2);
const bool persistent = args->GetBool(3);
if (handler_set_.empty()) {
// No handlers so cancel the query.
CancelUnhandledQuery(browser, frame, context_id, request_id);
return true;
}
const int browser_id = browser->GetIdentifier();
const int64 query_id = query_id_generator_.GetNextId();
CefRefPtr<CallbackImpl> callback(
new CallbackImpl(this, browser_id, query_id, persistent));
// Make a copy of the handler list in case the user adds or removes a
// handler while we're iterating.
HandlerSet handler_set = handler_set_;
bool handled = false;
HandlerSet::const_iterator it_handler = handler_set.begin();
for (; it_handler != handler_set.end(); ++it_handler) {
handled = (*it_handler)
->OnQuery(browser, frame, query_id, request, persistent,
callback.get());
if (handled)
break;
}
// If the query isn't handled nothing should be keeping a reference to
// the callback.
DCHECK(handled || callback->HasOneRef());
if (handled) {
// Persist the query information until the callback executes.
// It's safe to do this here because the callback will execute
// asynchronously.
QueryInfo* info = new QueryInfo;
info->browser = browser;
info->frame = frame;
info->context_id = context_id;
info->request_id = request_id;
info->persistent = persistent;
info->callback = callback;
info->handler = *(it_handler);
browser_query_info_map_.Add(browser_id, query_id, info);
} else {
// Invalidate the callback.
callback->Detach();
// No one chose to handle the query so cancel it.
CancelUnhandledQuery(browser, frame, context_id, request_id);
}
return true;
} else if (message_name == cancel_message_name_) {
CefRefPtr<CefListValue> args = message->GetArgumentList();
DCHECK_EQ(args->GetSize(), 2U);
const int browser_id = browser->GetIdentifier();
const int context_id = args->GetInt(0);
const int request_id = args->GetInt(1);
CancelPendingRequest(browser_id, context_id, request_id);
return true;
}
return false;
}