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/renderer/pepper/content_renderer_pepper_host_factory.h" 6 7#include "base/logging.h" 8#include "base/strings/string_util.h" 9#include "content/public/common/content_client.h" 10#include "content/public/renderer/content_renderer_client.h" 11#include "content/renderer/pepper/pepper_audio_input_host.h" 12#include "content/renderer/pepper/pepper_compositor_host.h" 13#include "content/renderer/pepper/pepper_file_chooser_host.h" 14#include "content/renderer/pepper/pepper_file_ref_renderer_host.h" 15#include "content/renderer/pepper/pepper_file_system_host.h" 16#include "content/renderer/pepper/pepper_graphics_2d_host.h" 17#include "content/renderer/pepper/pepper_media_stream_video_track_host.h" 18#include "content/renderer/pepper/pepper_plugin_instance_impl.h" 19#include "content/renderer/pepper/pepper_url_loader_host.h" 20#include "content/renderer/pepper/pepper_video_capture_host.h" 21#include "content/renderer/pepper/pepper_video_decoder_host.h" 22#include "content/renderer/pepper/pepper_video_destination_host.h" 23#include "content/renderer/pepper/pepper_video_source_host.h" 24#include "content/renderer/pepper/pepper_websocket_host.h" 25#include "content/renderer/pepper/ppb_image_data_impl.h" 26#include "content/renderer/pepper/renderer_ppapi_host_impl.h" 27#include "ppapi/host/resource_host.h" 28#include "ppapi/proxy/ppapi_message_utils.h" 29#include "ppapi/proxy/ppapi_messages.h" 30#include "ppapi/proxy/serialized_structs.h" 31#include "ppapi/shared_impl/ppb_image_data_shared.h" 32#include "third_party/WebKit/public/platform/WebURL.h" 33#include "third_party/WebKit/public/web/WebDocument.h" 34#include "third_party/WebKit/public/web/WebElement.h" 35#include "third_party/WebKit/public/web/WebPluginContainer.h" 36 37using ppapi::host::ResourceHost; 38using ppapi::UnpackMessage; 39 40namespace content { 41 42namespace { 43 44#if defined(ENABLE_WEBRTC) 45bool CanUseMediaStreamAPI(const RendererPpapiHost* host, PP_Instance instance) { 46 blink::WebPluginContainer* container = 47 host->GetContainerForInstance(instance); 48 if (!container) 49 return false; 50 51 GURL document_url = container->element().document().url(); 52 ContentRendererClient* content_renderer_client = 53 GetContentClient()->renderer(); 54 return content_renderer_client->AllowPepperMediaStreamAPI(document_url); 55} 56#endif // defined(ENABLE_WEBRTC) 57 58bool CanUseCompositorAPI(const RendererPpapiHost* host, PP_Instance instance) { 59 blink::WebPluginContainer* container = 60 host->GetContainerForInstance(instance); 61 if (!container) 62 return false; 63 64 GURL document_url = container->element().document().url(); 65 ContentRendererClient* content_renderer_client = 66 GetContentClient()->renderer(); 67 return content_renderer_client->IsPluginAllowedToUseCompositorAPI( 68 document_url); 69} 70 71bool CanUseVideoDecodeAPI(const RendererPpapiHost* host, PP_Instance instance) { 72 blink::WebPluginContainer* container = 73 host->GetContainerForInstance(instance); 74 if (!container) 75 return false; 76 77 GURL document_url = container->element().document().url(); 78 ContentRendererClient* content_renderer_client = 79 GetContentClient()->renderer(); 80 return content_renderer_client->IsPluginAllowedToUseVideoDecodeAPI( 81 document_url); 82} 83 84} // namespace 85 86ContentRendererPepperHostFactory::ContentRendererPepperHostFactory( 87 RendererPpapiHostImpl* host) 88 : host_(host) {} 89 90ContentRendererPepperHostFactory::~ContentRendererPepperHostFactory() {} 91 92scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( 93 ppapi::host::PpapiHost* host, 94 const ppapi::proxy::ResourceMessageCallParams& params, 95 PP_Instance instance, 96 const IPC::Message& message) { 97 DCHECK(host == host_->GetPpapiHost()); 98 99 // Make sure the plugin is giving us a valid instance for this resource. 100 if (!host_->IsValidInstance(instance)) 101 return scoped_ptr<ResourceHost>(); 102 103 PepperPluginInstanceImpl* instance_impl = 104 host_->GetPluginInstanceImpl(instance); 105 if (!instance_impl->render_frame()) 106 return scoped_ptr<ResourceHost>(); 107 108 // Public interfaces. 109 switch (message.type()) { 110 case PpapiHostMsg_Compositor_Create::ID: { 111 if (!CanUseCompositorAPI(host_, instance)) 112 return scoped_ptr<ResourceHost>(); 113 return scoped_ptr<ResourceHost>( 114 new PepperCompositorHost(host_, instance, params.pp_resource())); 115 } 116 case PpapiHostMsg_FileRef_CreateForFileAPI::ID: { 117 PP_Resource file_system; 118 std::string internal_path; 119 if (!UnpackMessage<PpapiHostMsg_FileRef_CreateForFileAPI>( 120 message, &file_system, &internal_path)) { 121 NOTREACHED(); 122 return scoped_ptr<ResourceHost>(); 123 } 124 return scoped_ptr<ResourceHost>(new PepperFileRefRendererHost( 125 host_, instance, params.pp_resource(), file_system, internal_path)); 126 } 127 case PpapiHostMsg_FileSystem_Create::ID: { 128 PP_FileSystemType file_system_type; 129 if (!UnpackMessage<PpapiHostMsg_FileSystem_Create>(message, 130 &file_system_type)) { 131 NOTREACHED(); 132 return scoped_ptr<ResourceHost>(); 133 } 134 return scoped_ptr<ResourceHost>(new PepperFileSystemHost( 135 host_, instance, params.pp_resource(), file_system_type)); 136 } 137 case PpapiHostMsg_Graphics2D_Create::ID: { 138 PP_Size size; 139 PP_Bool is_always_opaque; 140 if (!UnpackMessage<PpapiHostMsg_Graphics2D_Create>( 141 message, &size, &is_always_opaque)) { 142 NOTREACHED(); 143 return scoped_ptr<ResourceHost>(); 144 } 145 scoped_refptr<PPB_ImageData_Impl> image_data(new PPB_ImageData_Impl( 146 instance, ppapi::PPB_ImageData_Shared::PLATFORM)); 147 return scoped_ptr<ResourceHost>( 148 PepperGraphics2DHost::Create(host_, 149 instance, 150 params.pp_resource(), 151 size, 152 is_always_opaque, 153 image_data)); 154 } 155 case PpapiHostMsg_URLLoader_Create::ID: 156 return scoped_ptr<ResourceHost>(new PepperURLLoaderHost( 157 host_, false, instance, params.pp_resource())); 158 case PpapiHostMsg_VideoDecoder_Create::ID: { 159 if (!CanUseVideoDecodeAPI(host_, instance)) 160 return scoped_ptr<ResourceHost>(); 161 return scoped_ptr<ResourceHost>( 162 new PepperVideoDecoderHost(host_, instance, params.pp_resource())); 163 } 164 case PpapiHostMsg_WebSocket_Create::ID: 165 return scoped_ptr<ResourceHost>( 166 new PepperWebSocketHost(host_, instance, params.pp_resource())); 167#if defined(ENABLE_WEBRTC) 168 case PpapiHostMsg_MediaStreamVideoTrack_Create::ID: 169 return scoped_ptr<ResourceHost>(new PepperMediaStreamVideoTrackHost( 170 host_, instance, params.pp_resource())); 171 // These private MediaStream interfaces are exposed as if they were public 172 // so they can be used by NaCl plugins. However, they are available only 173 // for whitelisted apps. 174 case PpapiHostMsg_VideoDestination_Create::ID: 175 if (CanUseMediaStreamAPI(host_, instance)) 176 return scoped_ptr<ResourceHost>(new PepperVideoDestinationHost( 177 host_, instance, params.pp_resource())); 178 case PpapiHostMsg_VideoSource_Create::ID: 179 if (CanUseMediaStreamAPI(host_, instance)) 180 return scoped_ptr<ResourceHost>( 181 new PepperVideoSourceHost(host_, instance, params.pp_resource())); 182#endif // defined(ENABLE_WEBRTC) 183 } 184 185 // Dev interfaces. 186 if (GetPermissions().HasPermission(ppapi::PERMISSION_DEV)) { 187 switch (message.type()) { 188 case PpapiHostMsg_AudioInput_Create::ID: 189 return scoped_ptr<ResourceHost>( 190 new PepperAudioInputHost(host_, instance, params.pp_resource())); 191 case PpapiHostMsg_FileChooser_Create::ID: 192 return scoped_ptr<ResourceHost>( 193 new PepperFileChooserHost(host_, instance, params.pp_resource())); 194 case PpapiHostMsg_VideoCapture_Create::ID: { 195 PepperVideoCaptureHost* host = 196 new PepperVideoCaptureHost(host_, instance, params.pp_resource()); 197 if (!host->Init()) { 198 delete host; 199 return scoped_ptr<ResourceHost>(); 200 } 201 return scoped_ptr<ResourceHost>(host); 202 } 203 } 204 } 205 206 return scoped_ptr<ResourceHost>(); 207} 208 209const ppapi::PpapiPermissions& 210ContentRendererPepperHostFactory::GetPermissions() const { 211 return host_->GetPpapiHost()->permissions(); 212} 213 214} // namespace content 215