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_io_host.h"
10 #include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
11 #include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
12 #include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h"
13 #include "content/browser/renderer_host/pepper/pepper_gamepad_host.h"
14 #include "content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h"
15 #include "content/browser/renderer_host/pepper/pepper_network_monitor_host.h"
16 #include "content/browser/renderer_host/pepper/pepper_network_proxy_host.h"
17 #include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h"
18 #include "content/browser/renderer_host/pepper/pepper_printing_host.h"
19 #include "content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h"
20 #include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h"
21 #include "content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h"
22 #include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h"
23 #include "ppapi/host/message_filter_host.h"
24 #include "ppapi/host/ppapi_host.h"
25 #include "ppapi/host/resource_host.h"
26 #include "ppapi/proxy/ppapi_messages.h"
27 #include "ppapi/shared_impl/ppapi_permissions.h"
29 using ppapi::host::MessageFilterHost
;
30 using ppapi::host::ResourceHost
;
31 using ppapi::host::ResourceMessageFilter
;
32 using ppapi::UnpackMessage
;
38 const size_t kMaxSocketsAllowed
= 1024;
40 bool CanCreateSocket() {
42 PepperTCPServerSocketMessageFilter::GetNumInstances() +
43 PepperTCPSocketMessageFilter::GetNumInstances() +
44 PepperUDPSocketMessageFilter::GetNumInstances() <
50 ContentBrowserPepperHostFactory::ContentBrowserPepperHostFactory(
51 BrowserPpapiHostImpl
* host
)
55 ContentBrowserPepperHostFactory::~ContentBrowserPepperHostFactory() {
58 scoped_ptr
<ResourceHost
> ContentBrowserPepperHostFactory::CreateResourceHost(
59 ppapi::host::PpapiHost
* host
,
60 const ppapi::proxy::ResourceMessageCallParams
& params
,
62 const IPC::Message
& message
) {
63 DCHECK(host
== host_
->GetPpapiHost());
65 // Make sure the plugin is giving us a valid instance for this resource.
66 if (!host_
->IsValidInstance(instance
))
67 return scoped_ptr
<ResourceHost
>();
70 switch (message
.type()) {
71 case PpapiHostMsg_FileIO_Create::ID
: {
72 return scoped_ptr
<ResourceHost
>(new PepperFileIOHost(
73 host_
, instance
, params
.pp_resource()));
75 case PpapiHostMsg_FileSystem_Create::ID
: {
76 PP_FileSystemType file_system_type
;
77 if (!ppapi::UnpackMessage
<PpapiHostMsg_FileSystem_Create
>(message
,
80 return scoped_ptr
<ResourceHost
>();
82 return scoped_ptr
<ResourceHost
>(new PepperFileSystemBrowserHost(
83 host_
, instance
, params
.pp_resource(), file_system_type
));
85 case PpapiHostMsg_Gamepad_Create::ID
: {
86 return scoped_ptr
<ResourceHost
>(new PepperGamepadHost(
87 host_
, instance
, params
.pp_resource()));
89 case PpapiHostMsg_NetworkProxy_Create::ID
: {
90 return scoped_ptr
<ResourceHost
>(new PepperNetworkProxyHost(
91 host_
, instance
, params
.pp_resource()));
93 case PpapiHostMsg_HostResolver_Create::ID
: {
94 scoped_refptr
<ResourceMessageFilter
> host_resolver(
95 new PepperHostResolverMessageFilter(host_
, instance
, false));
96 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
97 host_
->GetPpapiHost(), instance
, params
.pp_resource(),
100 case PpapiHostMsg_FileRef_CreateInternal::ID
: {
101 PP_Resource file_system
;
102 std::string internal_path
;
103 if (!UnpackMessage
<PpapiHostMsg_FileRef_CreateInternal
>(
104 message
, &file_system
, &internal_path
)) {
106 return scoped_ptr
<ResourceHost
>();
108 return scoped_ptr
<ResourceHost
>(new PepperFileRefHost(
109 host_
, instance
, params
.pp_resource(), file_system
, internal_path
));
111 case PpapiHostMsg_TCPSocket_Create::ID
: {
112 ppapi::TCPSocketVersion version
;
113 if (!UnpackMessage
<PpapiHostMsg_TCPSocket_Create
>(message
, &version
) ||
114 version
== ppapi::TCP_SOCKET_VERSION_PRIVATE
) {
115 return scoped_ptr
<ResourceHost
>();
118 return CreateNewTCPSocket(instance
, params
.pp_resource(), version
);
120 case PpapiHostMsg_UDPSocket_Create::ID
: {
121 if (CanCreateSocket()) {
122 scoped_refptr
<ResourceMessageFilter
> udp_socket(
123 new PepperUDPSocketMessageFilter(host_
, instance
, false));
124 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
125 host_
->GetPpapiHost(), instance
, params
.pp_resource(), udp_socket
));
127 return scoped_ptr
<ResourceHost
>();
133 if (GetPermissions().HasPermission(ppapi::PERMISSION_DEV
)) {
134 switch (message
.type()) {
135 case PpapiHostMsg_Printing_Create::ID
: {
136 scoped_ptr
<PepperPrintSettingsManager
> manager(
137 new PepperPrintSettingsManagerImpl());
138 return scoped_ptr
<ResourceHost
>(new PepperPrintingHost(
139 host_
->GetPpapiHost(), instance
,
140 params
.pp_resource(), manager
.Pass()));
142 case PpapiHostMsg_TrueTypeFontSingleton_Create::ID
: {
143 return scoped_ptr
<ResourceHost
>(new PepperTrueTypeFontListHost(
144 host_
, instance
, params
.pp_resource()));
149 // Private interfaces.
150 if (GetPermissions().HasPermission(ppapi::PERMISSION_PRIVATE
)) {
151 switch (message
.type()) {
152 case PpapiHostMsg_BrowserFontSingleton_Create::ID
:
153 return scoped_ptr
<ResourceHost
>(new PepperBrowserFontSingletonHost(
154 host_
, instance
, params
.pp_resource()));
158 // Permissions for the following interfaces will be checked at the
159 // time of the corresponding instance's methods calls (because
160 // permission check can be performed only on the UI
161 // thread). Currently these interfaces are available only for
162 // whitelisted apps which may not have access to the other private
164 if (message
.type() == PpapiHostMsg_HostResolver_CreatePrivate::ID
) {
165 scoped_refptr
<ResourceMessageFilter
> host_resolver(
166 new PepperHostResolverMessageFilter(host_
, instance
, true));
167 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
168 host_
->GetPpapiHost(), instance
, params
.pp_resource(), host_resolver
));
170 if (message
.type() == PpapiHostMsg_TCPServerSocket_CreatePrivate::ID
) {
171 if (CanCreateSocket()) {
172 scoped_refptr
<ResourceMessageFilter
> tcp_server_socket(
173 new PepperTCPServerSocketMessageFilter(this, host_
, instance
, true));
174 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
175 host_
->GetPpapiHost(), instance
, params
.pp_resource(),
178 return scoped_ptr
<ResourceHost
>();
181 if (message
.type() == PpapiHostMsg_TCPSocket_CreatePrivate::ID
) {
182 return CreateNewTCPSocket(instance
, params
.pp_resource(),
183 ppapi::TCP_SOCKET_VERSION_PRIVATE
);
185 if (message
.type() == PpapiHostMsg_UDPSocket_CreatePrivate::ID
) {
186 if (CanCreateSocket()) {
187 scoped_refptr
<ResourceMessageFilter
> udp_socket(
188 new PepperUDPSocketMessageFilter(host_
, instance
, true));
189 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
190 host_
->GetPpapiHost(), instance
, params
.pp_resource(), udp_socket
));
192 return scoped_ptr
<ResourceHost
>();
195 if (message
.type() == PpapiHostMsg_NetworkMonitor_Create::ID
) {
196 return scoped_ptr
<ResourceHost
>(
197 new PepperNetworkMonitorHost(host_
, instance
, params
.pp_resource()));
201 if (GetPermissions().HasPermission(ppapi::PERMISSION_FLASH
)) {
202 switch (message
.type()) {
203 case PpapiHostMsg_FlashFile_Create::ID
: {
204 scoped_refptr
<ResourceMessageFilter
> file_filter(
205 new PepperFlashFileMessageFilter(instance
, host_
));
206 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
207 host_
->GetPpapiHost(), instance
, params
.pp_resource(),
213 return scoped_ptr
<ResourceHost
>();
216 scoped_ptr
<ppapi::host::ResourceHost
>
217 ContentBrowserPepperHostFactory::CreateAcceptedTCPSocket(
218 PP_Instance instance
,
219 ppapi::TCPSocketVersion version
,
220 scoped_ptr
<net::TCPSocket
> socket
) {
221 if (!CanCreateSocket())
222 return scoped_ptr
<ResourceHost
>();
223 scoped_refptr
<ResourceMessageFilter
> tcp_socket(
224 new PepperTCPSocketMessageFilter(host_
, instance
, version
,
226 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
227 host_
->GetPpapiHost(), instance
, 0, tcp_socket
));
230 scoped_ptr
<ppapi::host::ResourceHost
>
231 ContentBrowserPepperHostFactory::CreateNewTCPSocket(
232 PP_Instance instance
,
233 PP_Resource resource
,
234 ppapi::TCPSocketVersion version
) {
235 if (!CanCreateSocket())
236 return scoped_ptr
<ResourceHost
>();
238 scoped_refptr
<ResourceMessageFilter
> tcp_socket(
239 new PepperTCPSocketMessageFilter(this, host_
, instance
, version
));
241 return scoped_ptr
<ResourceHost
>();
243 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
244 host_
->GetPpapiHost(), instance
, resource
, tcp_socket
));
247 const ppapi::PpapiPermissions
&
248 ContentBrowserPepperHostFactory::GetPermissions() const {
249 return host_
->GetPpapiHost()->permissions();
252 } // namespace content