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 "ppapi/proxy/ppb_core_proxy.h" 6 7 #include <stdlib.h> // For malloc 8 9 #include "base/bind.h" 10 #include "base/debug/trace_event.h" 11 #include "base/logging.h" 12 #include "base/time/time.h" 13 #include "ppapi/c/pp_completion_callback.h" 14 #include "ppapi/c/pp_resource.h" 15 #include "ppapi/c/ppb_core.h" 16 #include "ppapi/proxy/plugin_dispatcher.h" 17 #include "ppapi/proxy/plugin_resource_tracker.h" 18 #include "ppapi/proxy/ppapi_messages.h" 19 #include "ppapi/shared_impl/ppapi_globals.h" 20 #include "ppapi/shared_impl/proxy_lock.h" 21 #include "ppapi/shared_impl/time_conversion.h" 22 23 namespace ppapi { 24 namespace proxy { 25 26 namespace { 27 28 void AddRefResource(PP_Resource resource) { 29 ppapi::ProxyAutoLock lock; 30 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(resource); 31 } 32 33 void ReleaseResource(PP_Resource resource) { 34 ppapi::ProxyAutoLock lock; 35 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(resource); 36 } 37 38 double GetTime() { 39 return TimeToPPTime(base::Time::Now()); 40 } 41 42 double GetTimeTicks() { 43 return TimeTicksToPPTimeTicks(base::TimeTicks::Now()); 44 } 45 46 void CallbackWrapper(PP_CompletionCallback callback, int32_t result) { 47 TRACE_EVENT2("ppapi proxy", "CallOnMainThread callback", 48 "Func", reinterpret_cast<void*>(callback.func), 49 "UserData", callback.user_data); 50 CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); 51 } 52 53 void CallOnMainThread(int delay_in_ms, 54 PP_CompletionCallback callback, 55 int32_t result) { 56 DCHECK(callback.func); 57 #if defined(OS_NACL) 58 // Some NaCl apps pass a negative delay, so we just sanitize to 0, to run as 59 // soon as possible. MessageLoop checks that the delay is non-negative. 60 if (delay_in_ms < 0) 61 delay_in_ms = 0; 62 #endif 63 if (!callback.func) 64 return; 65 ProxyAutoLock lock; 66 PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostDelayedTask( 67 FROM_HERE, 68 RunWhileLocked(base::Bind(&CallbackWrapper, callback, result)), 69 base::TimeDelta::FromMilliseconds(delay_in_ms)); 70 } 71 72 PP_Bool IsMainThread() { 73 return PP_FromBool(PpapiGlobals::Get()-> 74 GetMainThreadMessageLoop()->BelongsToCurrentThread()); 75 } 76 77 const PPB_Core core_interface = { 78 &AddRefResource, 79 &ReleaseResource, 80 &GetTime, 81 &GetTimeTicks, 82 &CallOnMainThread, 83 &IsMainThread 84 }; 85 86 } // namespace 87 88 PPB_Core_Proxy::PPB_Core_Proxy(Dispatcher* dispatcher) 89 : InterfaceProxy(dispatcher), 90 ppb_core_impl_(NULL) { 91 if (!dispatcher->IsPlugin()) { 92 ppb_core_impl_ = static_cast<const PPB_Core*>( 93 dispatcher->local_get_interface()(PPB_CORE_INTERFACE)); 94 } 95 } 96 97 PPB_Core_Proxy::~PPB_Core_Proxy() { 98 } 99 100 // static 101 const PPB_Core* PPB_Core_Proxy::GetPPB_Core_Interface() { 102 return &core_interface; 103 } 104 105 bool PPB_Core_Proxy::OnMessageReceived(const IPC::Message& msg) { 106 #if defined(OS_NACL) 107 return false; 108 #else 109 bool handled = true; 110 IPC_BEGIN_MESSAGE_MAP(PPB_Core_Proxy, msg) 111 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_AddRefResource, 112 OnMsgAddRefResource) 113 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_ReleaseResource, 114 OnMsgReleaseResource) 115 IPC_MESSAGE_UNHANDLED(handled = false) 116 IPC_END_MESSAGE_MAP() 117 // TODO(brettw) handle bad messages! 118 return handled; 119 #endif 120 } 121 122 #if !defined(OS_NACL) 123 void PPB_Core_Proxy::OnMsgAddRefResource(const HostResource& resource) { 124 ppb_core_impl_->AddRefResource(resource.host_resource()); 125 } 126 127 void PPB_Core_Proxy::OnMsgReleaseResource(const HostResource& resource) { 128 ppb_core_impl_->ReleaseResource(resource.host_resource()); 129 } 130 #endif // !defined(OS_NACL) 131 132 } // namespace proxy 133 } // namespace ppapi 134