1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h"
7 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
8 #include "content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h"
9 #include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
10 #include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
11 #include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h"
12 #include "content/browser/renderer_host/pepper/pepper_gamepad_host.h"
13 #include "content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h"
14 #include "content/browser/renderer_host/pepper/pepper_network_monitor_host.h"
15 #include "content/browser/renderer_host/pepper/pepper_network_proxy_host.h"
16 #include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h"
17 #include "content/browser/renderer_host/pepper/pepper_printing_host.h"
18 #include "content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h"
19 #include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h"
20 #include "content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h"
21 #include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h"
22 #include "ppapi/host/message_filter_host.h"
23 #include "ppapi/host/ppapi_host.h"
24 #include "ppapi/host/resource_host.h"
25 #include "ppapi/proxy/ppapi_messages.h"
26 #include "ppapi/shared_impl/ppapi_permissions.h"
28 using ppapi::host::MessageFilterHost;
29 using ppapi::host::ResourceHost;
30 using ppapi::host::ResourceMessageFilter;
31 using ppapi::UnpackMessage;
37 const size_t kMaxSocketsAllowed = 1024;
39 bool CanCreateSocket() {
41 PepperTCPServerSocketMessageFilter::GetNumInstances() +
42 PepperTCPSocketMessageFilter::GetNumInstances() +
43 PepperUDPSocketMessageFilter::GetNumInstances() <
49 ContentBrowserPepperHostFactory::ContentBrowserPepperHostFactory(
50 BrowserPpapiHostImpl* host)
54 ContentBrowserPepperHostFactory::~ContentBrowserPepperHostFactory() {
57 scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost(
58 ppapi::host::PpapiHost* host,
59 const ppapi::proxy::ResourceMessageCallParams& params,
61 const IPC::Message& message) {
62 DCHECK(host == host_->GetPpapiHost());
64 // Make sure the plugin is giving us a valid instance for this resource.
65 if (!host_->IsValidInstance(instance))
66 return scoped_ptr<ResourceHost>();
69 switch (message.type()) {
70 case PpapiHostMsg_FileSystem_Create::ID: {
71 PP_FileSystemType file_system_type;
72 if (!ppapi::UnpackMessage<PpapiHostMsg_FileSystem_Create>(message,
75 return scoped_ptr<ResourceHost>();
77 return scoped_ptr<ResourceHost>(new PepperFileSystemBrowserHost(
78 host_, instance, params.pp_resource(), file_system_type));
80 case PpapiHostMsg_Gamepad_Create::ID: {
81 return scoped_ptr<ResourceHost>(new PepperGamepadHost(
82 host_, instance, params.pp_resource()));
84 case PpapiHostMsg_NetworkProxy_Create::ID: {
85 return scoped_ptr<ResourceHost>(new PepperNetworkProxyHost(
86 host_, instance, params.pp_resource()));
88 case PpapiHostMsg_HostResolver_Create::ID: {
89 scoped_refptr<ResourceMessageFilter> host_resolver(
90 new PepperHostResolverMessageFilter(host_, instance, false));
91 return scoped_ptr<ResourceHost>(new MessageFilterHost(
92 host_->GetPpapiHost(), instance, params.pp_resource(),
95 case PpapiHostMsg_FileRef_CreateInternal::ID: {
96 PP_Resource file_system;
97 std::string internal_path;
98 if (!UnpackMessage<PpapiHostMsg_FileRef_CreateInternal>(
99 message, &file_system, &internal_path)) {
101 return scoped_ptr<ResourceHost>();
103 return scoped_ptr<ResourceHost>(new PepperFileRefHost(
104 host_, instance, params.pp_resource(), file_system, internal_path));
106 case PpapiHostMsg_TCPSocket_Create::ID: {
107 ppapi::TCPSocketVersion version;
108 if (!UnpackMessage<PpapiHostMsg_TCPSocket_Create>(message, &version) ||
109 version == ppapi::TCP_SOCKET_VERSION_PRIVATE) {
110 return scoped_ptr<ResourceHost>();
113 return CreateNewTCPSocket(instance, params.pp_resource(), version);
115 case PpapiHostMsg_UDPSocket_Create::ID: {
116 if (CanCreateSocket()) {
117 scoped_refptr<ResourceMessageFilter> udp_socket(
118 new PepperUDPSocketMessageFilter(host_, instance, false));
119 return scoped_ptr<ResourceHost>(new MessageFilterHost(
120 host_->GetPpapiHost(), instance, params.pp_resource(), udp_socket));
122 return scoped_ptr<ResourceHost>();
128 if (GetPermissions().HasPermission(ppapi::PERMISSION_DEV)) {
129 switch (message.type()) {
130 case PpapiHostMsg_Printing_Create::ID: {
131 scoped_ptr<PepperPrintSettingsManager> manager(
132 new PepperPrintSettingsManagerImpl());
133 return scoped_ptr<ResourceHost>(new PepperPrintingHost(
134 host_->GetPpapiHost(), instance,
135 params.pp_resource(), manager.Pass()));
137 case PpapiHostMsg_TrueTypeFontSingleton_Create::ID: {
138 return scoped_ptr<ResourceHost>(new PepperTrueTypeFontListHost(
139 host_, instance, params.pp_resource()));
144 // Private interfaces.
145 if (GetPermissions().HasPermission(ppapi::PERMISSION_PRIVATE)) {
146 switch (message.type()) {
147 case PpapiHostMsg_BrowserFontSingleton_Create::ID:
148 return scoped_ptr<ResourceHost>(new PepperBrowserFontSingletonHost(
149 host_, instance, params.pp_resource()));
153 // Permissions for the following interfaces will be checked at the
154 // time of the corresponding instance's methods calls (because
155 // permission check can be performed only on the UI
156 // thread). Currently these interfaces are available only for
157 // whitelisted apps which may not have access to the other private
159 if (message.type() == PpapiHostMsg_HostResolver_CreatePrivate::ID) {
160 scoped_refptr<ResourceMessageFilter> host_resolver(
161 new PepperHostResolverMessageFilter(host_, instance, true));
162 return scoped_ptr<ResourceHost>(new MessageFilterHost(
163 host_->GetPpapiHost(), instance, params.pp_resource(), host_resolver));
165 if (message.type() == PpapiHostMsg_TCPServerSocket_CreatePrivate::ID) {
166 if (CanCreateSocket()) {
167 scoped_refptr<ResourceMessageFilter> tcp_server_socket(
168 new PepperTCPServerSocketMessageFilter(this, host_, instance, true));
169 return scoped_ptr<ResourceHost>(new MessageFilterHost(
170 host_->GetPpapiHost(), instance, params.pp_resource(),
173 return scoped_ptr<ResourceHost>();
176 if (message.type() == PpapiHostMsg_TCPSocket_CreatePrivate::ID) {
177 return CreateNewTCPSocket(instance, params.pp_resource(),
178 ppapi::TCP_SOCKET_VERSION_PRIVATE);
180 if (message.type() == PpapiHostMsg_UDPSocket_CreatePrivate::ID) {
181 if (CanCreateSocket()) {
182 scoped_refptr<ResourceMessageFilter> udp_socket(
183 new PepperUDPSocketMessageFilter(host_, instance, true));
184 return scoped_ptr<ResourceHost>(new MessageFilterHost(
185 host_->GetPpapiHost(), instance, params.pp_resource(), udp_socket));
187 return scoped_ptr<ResourceHost>();
190 if (message.type() == PpapiHostMsg_NetworkMonitor_Create::ID) {
191 return scoped_ptr<ResourceHost>(
192 new PepperNetworkMonitorHost(host_, instance, params.pp_resource()));
196 if (GetPermissions().HasPermission(ppapi::PERMISSION_FLASH)) {
197 switch (message.type()) {
198 case PpapiHostMsg_FlashFile_Create::ID: {
199 scoped_refptr<ResourceMessageFilter> file_filter(
200 new PepperFlashFileMessageFilter(instance, host_));
201 return scoped_ptr<ResourceHost>(new MessageFilterHost(
202 host_->GetPpapiHost(), instance, params.pp_resource(),
208 return scoped_ptr<ResourceHost>();
211 scoped_ptr<ppapi::host::ResourceHost>
212 ContentBrowserPepperHostFactory::CreateAcceptedTCPSocket(
213 PP_Instance instance,
214 ppapi::TCPSocketVersion version,
215 scoped_ptr<net::TCPSocket> socket) {
216 if (!CanCreateSocket())
217 return scoped_ptr<ResourceHost>();
218 scoped_refptr<ResourceMessageFilter> tcp_socket(
219 new PepperTCPSocketMessageFilter(host_, instance, version,
221 return scoped_ptr<ResourceHost>(new MessageFilterHost(
222 host_->GetPpapiHost(), instance, 0, tcp_socket));
225 scoped_ptr<ppapi::host::ResourceHost>
226 ContentBrowserPepperHostFactory::CreateNewTCPSocket(
227 PP_Instance instance,
228 PP_Resource resource,
229 ppapi::TCPSocketVersion version) {
230 if (!CanCreateSocket())
231 return scoped_ptr<ResourceHost>();
233 scoped_refptr<ResourceMessageFilter> tcp_socket(
234 new PepperTCPSocketMessageFilter(this, host_, instance, version));
236 return scoped_ptr<ResourceHost>();
238 return scoped_ptr<ResourceHost>(new MessageFilterHost(
239 host_->GetPpapiHost(), instance, resource, tcp_socket));
242 const ppapi::PpapiPermissions&
243 ContentBrowserPepperHostFactory::GetPermissions() const {
244 return host_->GetPpapiHost()->permissions();
247 } // namespace content