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/pepper_gamepad_host.h" 6 7 #include "base/bind.h" 8 #include "content/browser/gamepad/gamepad_service.h" 9 #include "content/public/browser/browser_ppapi_host.h" 10 #include "ppapi/c/pp_errors.h" 11 #include "ppapi/host/dispatch_host_message.h" 12 #include "ppapi/host/host_message_context.h" 13 #include "ppapi/host/ppapi_host.h" 14 #include "ppapi/proxy/ppapi_messages.h" 15 #include "ppapi/shared_impl/ppb_gamepad_shared.h" 16 17 namespace content { 18 19 PepperGamepadHost::PepperGamepadHost(BrowserPpapiHost* host, 20 PP_Instance instance, 21 PP_Resource resource) 22 : ResourceHost(host->GetPpapiHost(), instance, resource), 23 browser_ppapi_host_(host), 24 gamepad_service_(GamepadService::GetInstance()), 25 is_started_(false), 26 weak_factory_(this) {} 27 28 PepperGamepadHost::PepperGamepadHost(GamepadService* gamepad_service, 29 BrowserPpapiHost* host, 30 PP_Instance instance, 31 PP_Resource resource) 32 : ResourceHost(host->GetPpapiHost(), instance, resource), 33 browser_ppapi_host_(host), 34 gamepad_service_(gamepad_service), 35 is_started_(false), 36 weak_factory_(this) {} 37 38 PepperGamepadHost::~PepperGamepadHost() { 39 if (is_started_) 40 gamepad_service_->RemoveConsumer(this); 41 } 42 43 int32_t PepperGamepadHost::OnResourceMessageReceived( 44 const IPC::Message& msg, 45 ppapi::host::HostMessageContext* context) { 46 PPAPI_BEGIN_MESSAGE_MAP(PepperGamepadHost, msg) 47 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Gamepad_RequestMemory, 48 OnRequestMemory) 49 PPAPI_END_MESSAGE_MAP() 50 return PP_ERROR_FAILED; 51 } 52 53 int32_t PepperGamepadHost::OnRequestMemory( 54 ppapi::host::HostMessageContext* context) { 55 if (is_started_) 56 return PP_ERROR_FAILED; 57 58 gamepad_service_->ConsumerBecameActive(this); 59 is_started_ = true; 60 61 // Don't send the shared memory back until the user has interacted with the 62 // gamepad. This is to prevent fingerprinting and matches what the web 63 // platform does. 64 gamepad_service_->RegisterForUserGesture( 65 base::Bind(&PepperGamepadHost::GotUserGesture, 66 weak_factory_.GetWeakPtr(), 67 context->MakeReplyMessageContext())); 68 return PP_OK_COMPLETIONPENDING; 69 } 70 71 void PepperGamepadHost::GotUserGesture( 72 const ppapi::host::ReplyMessageContext& context) { 73 base::SharedMemoryHandle handle = 74 gamepad_service_->GetSharedMemoryHandleForProcess( 75 browser_ppapi_host_->GetPluginProcessHandle()); 76 77 context.params.AppendHandle(ppapi::proxy::SerializedHandle( 78 handle, sizeof(ppapi::ContentGamepadHardwareBuffer))); 79 host()->SendReply(context, PpapiPluginMsg_Gamepad_SendMemory()); 80 } 81 82 } // namespace content 83