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_host.h"
22 #include "content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h"
23 #include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h"
24 #include "ppapi/host/message_filter_host.h"
25 #include "ppapi/host/ppapi_host.h"
26 #include "ppapi/host/resource_host.h"
27 #include "ppapi/proxy/ppapi_messages.h"
28 #include "ppapi/shared_impl/ppapi_permissions.h"
30 using ppapi::host::MessageFilterHost
;
31 using ppapi::host::ResourceHost
;
32 using ppapi::host::ResourceMessageFilter
;
33 using ppapi::proxy::SerializedTrueTypeFontDesc
;
34 using ppapi::UnpackMessage
;
40 const size_t kMaxSocketsAllowed
= 1024;
42 bool CanCreateSocket() {
43 return PepperTCPServerSocketMessageFilter::GetNumInstances() +
44 PepperTCPSocketMessageFilter::GetNumInstances() +
45 PepperUDPSocketMessageFilter::GetNumInstances() <
51 ContentBrowserPepperHostFactory::ContentBrowserPepperHostFactory(
52 BrowserPpapiHostImpl
* host
)
55 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_FileIO_Create::ID
: {
71 return scoped_ptr
<ResourceHost
>(
72 new PepperFileIOHost(host_
, instance
, params
.pp_resource()));
74 case PpapiHostMsg_FileSystem_Create::ID
: {
75 PP_FileSystemType file_system_type
;
76 if (!ppapi::UnpackMessage
<PpapiHostMsg_FileSystem_Create
>(
77 message
, &file_system_type
)) {
79 return scoped_ptr
<ResourceHost
>();
81 return scoped_ptr
<ResourceHost
>(new PepperFileSystemBrowserHost(
82 host_
, instance
, params
.pp_resource(), file_system_type
));
84 case PpapiHostMsg_Gamepad_Create::ID
: {
85 return scoped_ptr
<ResourceHost
>(
86 new PepperGamepadHost(host_
, instance
, params
.pp_resource()));
88 case PpapiHostMsg_NetworkProxy_Create::ID
: {
89 return scoped_ptr
<ResourceHost
>(
90 new PepperNetworkProxyHost(host_
, instance
, params
.pp_resource()));
92 case PpapiHostMsg_HostResolver_Create::ID
: {
93 scoped_refptr
<ResourceMessageFilter
> host_resolver(
94 new PepperHostResolverMessageFilter(host_
, instance
, false));
95 return scoped_ptr
<ResourceHost
>(
96 new MessageFilterHost(host_
->GetPpapiHost(),
101 case PpapiHostMsg_FileRef_CreateForFileAPI::ID
: {
102 PP_Resource file_system
;
103 std::string internal_path
;
104 if (!UnpackMessage
<PpapiHostMsg_FileRef_CreateForFileAPI
>(
105 message
, &file_system
, &internal_path
)) {
107 return scoped_ptr
<ResourceHost
>();
109 return scoped_ptr
<ResourceHost
>(new PepperFileRefHost(
110 host_
, instance
, params
.pp_resource(), file_system
, internal_path
));
112 case PpapiHostMsg_TCPSocket_Create::ID
: {
113 ppapi::TCPSocketVersion version
;
114 if (!UnpackMessage
<PpapiHostMsg_TCPSocket_Create
>(message
, &version
) ||
115 version
== ppapi::TCP_SOCKET_VERSION_PRIVATE
) {
116 return scoped_ptr
<ResourceHost
>();
119 return CreateNewTCPSocket(instance
, params
.pp_resource(), version
);
121 case PpapiHostMsg_UDPSocket_Create::ID
: {
122 if (CanCreateSocket()) {
123 scoped_refptr
<ResourceMessageFilter
> udp_socket(
124 new PepperUDPSocketMessageFilter(host_
, instance
, false));
125 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
126 host_
->GetPpapiHost(), instance
, params
.pp_resource(), udp_socket
));
128 return scoped_ptr
<ResourceHost
>();
134 if (GetPermissions().HasPermission(ppapi::PERMISSION_DEV
)) {
135 switch (message
.type()) {
136 case PpapiHostMsg_Printing_Create::ID
: {
137 scoped_ptr
<PepperPrintSettingsManager
> manager(
138 new PepperPrintSettingsManagerImpl());
139 return scoped_ptr
<ResourceHost
>(
140 new PepperPrintingHost(host_
->GetPpapiHost(),
142 params
.pp_resource(),
145 case PpapiHostMsg_TrueTypeFont_Create::ID
: {
146 SerializedTrueTypeFontDesc desc
;
147 if (!UnpackMessage
<PpapiHostMsg_TrueTypeFont_Create
>(message
, &desc
)) {
149 return scoped_ptr
<ResourceHost
>();
151 // Check that the family name is valid UTF-8 before passing it to the
153 if (!base::IsStringUTF8(desc
.family
))
154 return scoped_ptr
<ResourceHost
>();
156 return scoped_ptr
<ResourceHost
>(new PepperTrueTypeFontHost(
157 host_
, instance
, params
.pp_resource(), desc
));
159 case PpapiHostMsg_TrueTypeFontSingleton_Create::ID
: {
160 return scoped_ptr
<ResourceHost
>(new PepperTrueTypeFontListHost(
161 host_
, instance
, params
.pp_resource()));
166 // Private interfaces.
167 if (GetPermissions().HasPermission(ppapi::PERMISSION_PRIVATE
)) {
168 switch (message
.type()) {
169 case PpapiHostMsg_BrowserFontSingleton_Create::ID
:
170 return scoped_ptr
<ResourceHost
>(new PepperBrowserFontSingletonHost(
171 host_
, instance
, params
.pp_resource()));
175 // Permissions for the following interfaces will be checked at the
176 // time of the corresponding instance's methods calls (because
177 // permission check can be performed only on the UI
178 // thread). Currently these interfaces are available only for
179 // whitelisted apps which may not have access to the other private
181 if (message
.type() == PpapiHostMsg_HostResolver_CreatePrivate::ID
) {
182 scoped_refptr
<ResourceMessageFilter
> host_resolver(
183 new PepperHostResolverMessageFilter(host_
, instance
, true));
184 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
185 host_
->GetPpapiHost(), instance
, params
.pp_resource(), host_resolver
));
187 if (message
.type() == PpapiHostMsg_TCPServerSocket_CreatePrivate::ID
) {
188 if (CanCreateSocket()) {
189 scoped_refptr
<ResourceMessageFilter
> tcp_server_socket(
190 new PepperTCPServerSocketMessageFilter(this, host_
, instance
, true));
191 return scoped_ptr
<ResourceHost
>(
192 new MessageFilterHost(host_
->GetPpapiHost(),
194 params
.pp_resource(),
197 return scoped_ptr
<ResourceHost
>();
200 if (message
.type() == PpapiHostMsg_TCPSocket_CreatePrivate::ID
) {
201 return CreateNewTCPSocket(
202 instance
, params
.pp_resource(), ppapi::TCP_SOCKET_VERSION_PRIVATE
);
204 if (message
.type() == PpapiHostMsg_UDPSocket_CreatePrivate::ID
) {
205 if (CanCreateSocket()) {
206 scoped_refptr
<ResourceMessageFilter
> udp_socket(
207 new PepperUDPSocketMessageFilter(host_
, instance
, true));
208 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
209 host_
->GetPpapiHost(), instance
, params
.pp_resource(), udp_socket
));
211 return scoped_ptr
<ResourceHost
>();
214 if (message
.type() == PpapiHostMsg_NetworkMonitor_Create::ID
) {
215 return scoped_ptr
<ResourceHost
>(
216 new PepperNetworkMonitorHost(host_
, instance
, params
.pp_resource()));
220 if (GetPermissions().HasPermission(ppapi::PERMISSION_FLASH
)) {
221 switch (message
.type()) {
222 case PpapiHostMsg_FlashFile_Create::ID
: {
223 scoped_refptr
<ResourceMessageFilter
> file_filter(
224 new PepperFlashFileMessageFilter(instance
, host_
));
225 return scoped_ptr
<ResourceHost
>(
226 new MessageFilterHost(host_
->GetPpapiHost(),
228 params
.pp_resource(),
234 return scoped_ptr
<ResourceHost
>();
237 scoped_ptr
<ppapi::host::ResourceHost
>
238 ContentBrowserPepperHostFactory::CreateAcceptedTCPSocket(
239 PP_Instance instance
,
240 ppapi::TCPSocketVersion version
,
241 scoped_ptr
<net::TCPSocket
> socket
) {
242 if (!CanCreateSocket())
243 return scoped_ptr
<ResourceHost
>();
244 scoped_refptr
<ResourceMessageFilter
> tcp_socket(
245 new PepperTCPSocketMessageFilter(
246 host_
, instance
, version
, socket
.Pass()));
247 return scoped_ptr
<ResourceHost
>(
248 new MessageFilterHost(host_
->GetPpapiHost(), instance
, 0, tcp_socket
));
251 scoped_ptr
<ppapi::host::ResourceHost
>
252 ContentBrowserPepperHostFactory::CreateNewTCPSocket(
253 PP_Instance instance
,
254 PP_Resource resource
,
255 ppapi::TCPSocketVersion version
) {
256 if (!CanCreateSocket())
257 return scoped_ptr
<ResourceHost
>();
259 scoped_refptr
<ResourceMessageFilter
> tcp_socket(
260 new PepperTCPSocketMessageFilter(this, host_
, instance
, version
));
261 if (!tcp_socket
.get())
262 return scoped_ptr
<ResourceHost
>();
264 return scoped_ptr
<ResourceHost
>(new MessageFilterHost(
265 host_
->GetPpapiHost(), instance
, resource
, tcp_socket
));
268 const ppapi::PpapiPermissions
& ContentBrowserPepperHostFactory::GetPermissions()
270 return host_
->GetPpapiHost()->permissions();
273 } // namespace content