content_browser_pepper_host_factory.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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. 4 5#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" 6 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" 27 28using ppapi::host::MessageFilterHost; 29using ppapi::host::ResourceHost; 30using ppapi::host::ResourceMessageFilter; 31using ppapi::UnpackMessage; 32 33namespace content { 34 35namespace { 36 37const size_t kMaxSocketsAllowed = 1024; 38 39bool CanCreateSocket() { 40 return 41 PepperTCPServerSocketMessageFilter::GetNumInstances() + 42 PepperTCPSocketMessageFilter::GetNumInstances() + 43 PepperUDPSocketMessageFilter::GetNumInstances() < 44 kMaxSocketsAllowed; 45} 46 47} // namespace 48 49ContentBrowserPepperHostFactory::ContentBrowserPepperHostFactory( 50 BrowserPpapiHostImpl* host) 51 : host_(host) { 52} 53 54ContentBrowserPepperHostFactory::~ContentBrowserPepperHostFactory() { 55} 56 57scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost( 58 ppapi::host::PpapiHost* host, 59 const ppapi::proxy::ResourceMessageCallParams& params, 60 PP_Instance instance, 61 const IPC::Message& message) { 62 DCHECK(host == host_->GetPpapiHost()); 63 64 // Make sure the plugin is giving us a valid instance for this resource. 65 if (!host_->IsValidInstance(instance)) 66 return scoped_ptr<ResourceHost>(); 67 68 // Public interfaces. 69 switch (message.type()) { 70 case PpapiHostMsg_FileSystem_Create::ID: { 71 PP_FileSystemType file_system_type; 72 if (!ppapi::UnpackMessage<PpapiHostMsg_FileSystem_Create>(message, 73 &file_system_type)) { 74 NOTREACHED(); 75 return scoped_ptr<ResourceHost>(); 76 } 77 return scoped_ptr<ResourceHost>(new PepperFileSystemBrowserHost( 78 host_, instance, params.pp_resource(), file_system_type)); 79 } 80 case PpapiHostMsg_Gamepad_Create::ID: { 81 return scoped_ptr<ResourceHost>(new PepperGamepadHost( 82 host_, instance, params.pp_resource())); 83 } 84 case PpapiHostMsg_NetworkProxy_Create::ID: { 85 return scoped_ptr<ResourceHost>(new PepperNetworkProxyHost( 86 host_, instance, params.pp_resource())); 87 } 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(), 93 host_resolver)); 94 } 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)) { 100 NOTREACHED(); 101 return scoped_ptr<ResourceHost>(); 102 } 103 return scoped_ptr<ResourceHost>(new PepperFileRefHost( 104 host_, instance, params.pp_resource(), file_system, internal_path)); 105 } 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>(); 111 } 112 113 return CreateNewTCPSocket(instance, params.pp_resource(), version); 114 } 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)); 121 } else { 122 return scoped_ptr<ResourceHost>(); 123 } 124 } 125 } 126 127 // Dev interfaces. 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())); 136 } 137 case PpapiHostMsg_TrueTypeFontSingleton_Create::ID: { 138 return scoped_ptr<ResourceHost>(new PepperTrueTypeFontListHost( 139 host_, instance, params.pp_resource())); 140 } 141 } 142 } 143 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())); 150 } 151 } 152 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 158 // interfaces. 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)); 164 } 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(), 171 tcp_server_socket)); 172 } else { 173 return scoped_ptr<ResourceHost>(); 174 } 175 } 176 if (message.type() == PpapiHostMsg_TCPSocket_CreatePrivate::ID) { 177 return CreateNewTCPSocket(instance, params.pp_resource(), 178 ppapi::TCP_SOCKET_VERSION_PRIVATE); 179 } 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)); 186 } else { 187 return scoped_ptr<ResourceHost>(); 188 } 189 } 190 if (message.type() == PpapiHostMsg_NetworkMonitor_Create::ID) { 191 return scoped_ptr<ResourceHost>( 192 new PepperNetworkMonitorHost(host_, instance, params.pp_resource())); 193 } 194 195 // Flash interfaces. 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(), 203 file_filter)); 204 } 205 } 206 } 207 208 return scoped_ptr<ResourceHost>(); 209} 210 211scoped_ptr<ppapi::host::ResourceHost> 212ContentBrowserPepperHostFactory::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, 220 socket.Pass())); 221 return scoped_ptr<ResourceHost>(new MessageFilterHost( 222 host_->GetPpapiHost(), instance, 0, tcp_socket)); 223} 224 225scoped_ptr<ppapi::host::ResourceHost> 226ContentBrowserPepperHostFactory::CreateNewTCPSocket( 227 PP_Instance instance, 228 PP_Resource resource, 229 ppapi::TCPSocketVersion version) { 230 if (!CanCreateSocket()) 231 return scoped_ptr<ResourceHost>(); 232 233 scoped_refptr<ResourceMessageFilter> tcp_socket( 234 new PepperTCPSocketMessageFilter(this, host_, instance, version)); 235 if (!tcp_socket) 236 return scoped_ptr<ResourceHost>(); 237 238 return scoped_ptr<ResourceHost>(new MessageFilterHost( 239 host_->GetPpapiHost(), instance, resource, tcp_socket)); 240} 241 242const ppapi::PpapiPermissions& 243ContentBrowserPepperHostFactory::GetPermissions() const { 244 return host_->GetPpapiHost()->permissions(); 245} 246 247} // namespace content 248