Index: content/browser/renderer_host/pepper/pepper_host_resolver_private_host.cc |
diff --git a/content/browser/renderer_host/pepper/pepper_host_resolver_private_host.cc b/content/browser/renderer_host/pepper/pepper_host_resolver_private_host.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6c253154d8d143f9857b91ac7085f9f57c8ddfef |
--- /dev/null |
+++ b/content/browser/renderer_host/pepper/pepper_host_resolver_private_host.cc |
@@ -0,0 +1,246 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/browser/renderer_host/pepper/pepper_host_resolver_private_host.h" |
+ |
+#include "base/logging.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/time.h" |
+#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" |
+#include "content/browser/renderer_host/pepper/pepper_lookup_request.h" |
+#include "content/browser/renderer_host/pepper/pepper_socket_utils.h" |
+#include "content/public/browser/browser_context.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/render_process_host.h" |
+#include "content/public/browser/resource_context.h" |
+#include "content/public/common/socket_permission_request.h" |
+#include "net/base/address_list.h" |
+#include "net/base/host_resolver.h" |
+#include "ppapi/c/private/ppb_host_resolver_private.h" |
+#include "ppapi/c/private/ppb_net_address_private.h" |
+#include "ppapi/host/dispatch_host_message.h" |
+#include "ppapi/host/ppapi_host.h" |
+#include "ppapi/proxy/host_resolver_private_resource.h" |
+#include "ppapi/proxy/ppapi_messages.h" |
+#include "ppapi/shared_impl/private/net_address_private_impl.h" |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+// Delay for resolve requests until host resolver is ready. |
+const int kHostResolverWaitingTimeoutMs = 100; |
+ |
+ResourceContext* GetResourceContext(RenderProcessHost* render_process_host) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ BrowserContext* browser_context = render_process_host->GetBrowserContext(); |
+ if (!browser_context) |
+ return NULL; |
+ return browser_context->GetResourceContext(); |
+} |
+ |
+void PrepareRequestInfo(const PP_HostResolver_Private_Hint& hint, |
+ net::HostResolver::RequestInfo* request_info) { |
+ DCHECK(request_info); |
+ |
+ net::AddressFamily address_family; |
+ switch (hint.family) { |
+ case PP_NETADDRESSFAMILY_IPV4: |
+ address_family = net::ADDRESS_FAMILY_IPV4; |
+ break; |
+ case PP_NETADDRESSFAMILY_IPV6: |
+ address_family = net::ADDRESS_FAMILY_IPV6; |
+ break; |
+ default: |
+ address_family = net::ADDRESS_FAMILY_UNSPECIFIED; |
+ } |
+ request_info->set_address_family(address_family); |
+ |
+ net::HostResolverFlags host_resolver_flags = 0; |
+ if (hint.flags & PP_HOST_RESOLVER_FLAGS_CANONNAME) |
+ host_resolver_flags |= net::HOST_RESOLVER_CANONNAME; |
+ if (hint.flags & PP_HOST_RESOLVER_FLAGS_LOOPBACK_ONLY) |
+ host_resolver_flags |= net::HOST_RESOLVER_LOOPBACK_ONLY; |
+ request_info->set_host_resolver_flags(host_resolver_flags); |
+} |
+ |
+void CreateNetAddressListFromAddressList( |
+ const net::AddressList& list, |
+ std::vector<PP_NetAddress_Private>* net_address_list) { |
+ DCHECK(net_address_list); |
+ |
+ net_address_list->clear(); |
+ net_address_list->reserve(list.size()); |
+ |
+ PP_NetAddress_Private address; |
+ for (size_t i = 0; i < list.size(); ++i) { |
+ if (!ppapi::NetAddressPrivateImpl::IPEndPointToNetAddress(list[i].address(), |
+ list[i].port(), |
+ &address)) { |
+ net_address_list->clear(); |
+ return; |
+ } |
+ net_address_list->push_back(address); |
+ } |
+} |
+ |
+} // namespace |
+ |
+PepperHostResolverPrivateHost::PepperHostResolverPrivateHost( |
+ BrowserPpapiHostImpl* host, |
+ PP_Instance instance, |
+ PP_Resource resource) |
+ : ResourceHost(host->GetPpapiHost(), instance, resource), |
+ host_(host), |
+ host_resolver_(NULL), |
+ host_resolver_is_ready_(false), |
+ weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
+ DCHECK(host); |
+ |
+ // Request host resolver. |
+ pepper_socket_utils::PostOnUIThreadWithRenderProcessHostAndReply( |
+ host_, |
+ FROM_HERE, |
+ instance, |
+ base::Bind(&GetResourceContext), |
+ base::Bind(&PepperHostResolverPrivateHost::SetHostResolver, |
+ weak_factory_.GetWeakPtr())); |
+} |
+ |
+PepperHostResolverPrivateHost::~PepperHostResolverPrivateHost() { |
+} |
+ |
+int32_t PepperHostResolverPrivateHost::OnResourceMessageReceived( |
+ const IPC::Message& msg, |
+ ppapi::host::HostMessageContext* context) { |
+ IPC_BEGIN_MESSAGE_MAP(PepperHostResolverPrivateHost, msg) |
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL( |
+ PpapiHostMsg_HostResolverPrivate_Resolve, |
+ OnMsgResolve) |
+ IPC_END_MESSAGE_MAP() |
+ return PP_ERROR_FAILED; |
+} |
+ |
+void PepperHostResolverPrivateHost::SetHostResolver( |
+ ResourceContext* resource_context) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ host_resolver_is_ready_ = true; |
yzshen1
2013/01/24 18:45:03
nit: |host_resolver_is_ready_| is not very accurat
ygorshenin1
2013/02/05 12:45:31
Done.
|
+ if (resource_context) |
+ host_resolver_ = resource_context->GetHostResolver(); |
+} |
+ |
+int32_t PepperHostResolverPrivateHost::OnMsgResolve( |
yzshen1
2013/01/24 18:45:03
Now that we have to jump to the UI thread to:
- ge
ygorshenin1
2013/02/05 12:45:31
Great idea. Code is much cleaner now. Thanks!
On
|
+ const ppapi::host::HostMessageContext* context, |
+ const ppapi::HostPortPair& host_port, |
+ const PP_HostResolver_Private_Hint& hint) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ OnResolve(context->MakeReplyMessageContext(), host_port, hint); |
+ return PP_OK_COMPLETIONPENDING; |
+} |
+ |
+void PepperHostResolverPrivateHost::OnResolve( |
+ const ppapi::host::ReplyMessageContext& context, |
+ const ppapi::HostPortPair& host_port, |
+ const PP_HostResolver_Private_Hint& hint) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ if (!host_resolver_is_ready()) { |
+ // Delay resolve request until host resolver is ready. |
+ BrowserThread::PostDelayedTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&PepperHostResolverPrivateHost::OnResolve, |
+ weak_factory_.GetWeakPtr(), |
+ context, host_port, hint), |
+ base::TimeDelta::FromMilliseconds(kHostResolverWaitingTimeoutMs)); |
+ return; |
+ } |
+ |
+ SocketPermissionRequest request( |
+ content::SocketPermissionRequest::NONE, "", 0); |
+ CheckSocketPermissionsAndReply( |
+ request, |
+ base::Bind(&PepperHostResolverPrivateHost::DoResolve, |
+ weak_factory_.GetWeakPtr(), |
+ context, host_port, hint)); |
+} |
+ |
+void PepperHostResolverPrivateHost::DoResolve( |
+ const ppapi::host::ReplyMessageContext& context, |
+ const ppapi::HostPortPair& host_port, |
+ const PP_HostResolver_Private_Hint& hint, |
+ bool allowed) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ if (!allowed || !host_resolver()) { |
+ SendResolveError(context); |
+ return; |
+ } |
+ |
+ net::HostResolver::RequestInfo request_info( |
+ net::HostPortPair(host_port.host, host_port.port)); |
+ PrepareRequestInfo(hint, &request_info); |
+ |
+ scoped_ptr<ReplyMessageContext> bound_info(new ReplyMessageContext(context)); |
+ |
+ // The lookup request will delete itself on completion. |
+ PepperLookupRequest<ReplyMessageContext>* lookup_request = |
+ new PepperLookupRequest<ReplyMessageContext>( |
+ host_resolver(), |
+ request_info, |
+ bound_info.release(), |
+ base::Bind(&PepperHostResolverPrivateHost::OnLookupFinished, |
+ weak_factory_.GetWeakPtr())); |
+ lookup_request->Start(); |
+} |
+ |
+void PepperHostResolverPrivateHost::OnLookupFinished( |
+ int result, |
+ const net::AddressList& addresses, |
+ const ReplyMessageContext& context) { |
+ if (result != net::OK) { |
+ SendResolveError(context); |
+ } else { |
+ const std::string& canonical_name = addresses.canonical_name(); |
+ NetAddressList net_address_list; |
+ CreateNetAddressListFromAddressList(addresses, &net_address_list); |
+ if (net_address_list.empty()) |
+ SendResolveError(context); |
+ else |
+ SendResolveReply(true, canonical_name, net_address_list, context); |
+ } |
+} |
+ |
+void PepperHostResolverPrivateHost::SendResolveReply( |
+ bool succeeded, |
+ const std::string& canonical_name, |
+ const NetAddressList& net_address_list, |
+ const ReplyMessageContext& context) { |
+ ppapi::host::ReplyMessageContext reply_context = context; |
+ reply_context.params.set_result(succeeded); |
+ host()->SendReply(reply_context, |
+ PpapiPluginMsg_HostResolverPrivate_ResolveReply( |
+ canonical_name, net_address_list)); |
+} |
+ |
+void PepperHostResolverPrivateHost::SendResolveError( |
+ const ReplyMessageContext& context) { |
+ SendResolveReply(false, "", NetAddressList(), context); |
+} |
+ |
+void PepperHostResolverPrivateHost::CheckSocketPermissionsAndReply( |
+ const SocketPermissionRequest& params, |
+ const PermissionCheckCallback& callback) { |
+ pepper_socket_utils::PostOnUIThreadWithRenderViewHostAndReply( |
+ host_, |
+ FROM_HERE, |
+ pp_instance(), |
+ base::Bind(&pepper_socket_utils::CanUseSocketAPIs, |
+ host_->plugin_process_type(), params), |
+ callback); |
+} |
+ |
+} // namespace content |