Home | History | Annotate | Download | only in proxy
      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   bool handled = true;
    107   IPC_BEGIN_MESSAGE_MAP(PPB_Core_Proxy, msg)
    108 #if !defined(OS_NACL)
    109     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_AddRefResource,
    110                         OnMsgAddRefResource)
    111     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_ReleaseResource,
    112                         OnMsgReleaseResource)
    113 #endif
    114     IPC_MESSAGE_UNHANDLED(handled = false)
    115   IPC_END_MESSAGE_MAP()
    116   // TODO(brettw) handle bad messages!
    117   return handled;
    118 }
    119 
    120 #if !defined(OS_NACL)
    121 void PPB_Core_Proxy::OnMsgAddRefResource(const HostResource& resource) {
    122   ppb_core_impl_->AddRefResource(resource.host_resource());
    123 }
    124 
    125 void PPB_Core_Proxy::OnMsgReleaseResource(const HostResource& resource) {
    126   ppb_core_impl_->ReleaseResource(resource.host_resource());
    127 }
    128 #endif  // !defined(OS_NACL)
    129 
    130 }  // namespace proxy
    131 }  // namespace ppapi
    132