summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/ppb_core_proxy.cc
blob: 52f965c124549a11df03283e8d5dbff2b31c95bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ppapi/proxy/ppb_core_proxy.h"

#include <stdlib.h>  // For malloc

#include "base/bind.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/time_conversion.h"

namespace ppapi {
namespace proxy {

namespace {

void AddRefResource(PP_Resource resource) {
  ppapi::ProxyAutoLock lock;
  PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(resource);
}

void ReleaseResource(PP_Resource resource) {
  ppapi::ProxyAutoLock lock;
  PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(resource);
}

double GetTime() {
  return TimeToPPTime(base::Time::Now());
}

double GetTimeTicks() {
  return TimeTicksToPPTimeTicks(base::TimeTicks::Now());
}

void CallbackWrapper(PP_CompletionCallback callback, int32_t result) {
  TRACE_EVENT2("ppapi proxy", "CallOnMainThread callback",
               "Func", reinterpret_cast<void*>(callback.func),
               "UserData", callback.user_data);
  CallWhileUnlocked(PP_RunCompletionCallback, &callback, result);
}

void CallOnMainThread(int delay_in_ms,
                      PP_CompletionCallback callback,
                      int32_t result) {
  DCHECK(callback.func);
#if defined(OS_NACL)
  // Some NaCl apps pass a negative delay, so we just sanitize to 0, to run as
  // soon as possible. MessageLoop checks that the delay is non-negative.
  if (delay_in_ms < 0)
    delay_in_ms = 0;
#endif
  if (!callback.func)
    return;
  ProxyAutoLock lock;
  PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostDelayedTask(
      FROM_HERE,
      RunWhileLocked(base::Bind(&CallbackWrapper, callback, result)),
      base::TimeDelta::FromMilliseconds(delay_in_ms));
}

PP_Bool IsMainThread() {
  return PP_FromBool(PpapiGlobals::Get()->
      GetMainThreadMessageLoop()->BelongsToCurrentThread());
}

const PPB_Core core_interface = {
  &AddRefResource,
  &ReleaseResource,
  &GetTime,
  &GetTimeTicks,
  &CallOnMainThread,
  &IsMainThread
};

}  // namespace

PPB_Core_Proxy::PPB_Core_Proxy(Dispatcher* dispatcher)
    : InterfaceProxy(dispatcher),
      ppb_core_impl_(NULL) {
  if (!dispatcher->IsPlugin()) {
    ppb_core_impl_ = static_cast<const PPB_Core*>(
        dispatcher->local_get_interface()(PPB_CORE_INTERFACE));
  }
}

PPB_Core_Proxy::~PPB_Core_Proxy() {
}

// static
const PPB_Core* PPB_Core_Proxy::GetPPB_Core_Interface() {
  return &core_interface;
}

bool PPB_Core_Proxy::OnMessageReceived(const IPC::Message& msg) {
#if defined(OS_NACL)
  return false;
#else
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(PPB_Core_Proxy, msg)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_AddRefResource,
                        OnMsgAddRefResource)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_ReleaseResource,
                        OnMsgReleaseResource)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  // TODO(brettw) handle bad messages!
  return handled;
#endif
}

#if !defined(OS_NACL)
void PPB_Core_Proxy::OnMsgAddRefResource(const HostResource& resource) {
  ppb_core_impl_->AddRefResource(resource.host_resource());
}

void PPB_Core_Proxy::OnMsgReleaseResource(const HostResource& resource) {
  ppb_core_impl_->ReleaseResource(resource.host_resource());
}
#endif  // !defined(OS_NACL)

}  // namespace proxy
}  // namespace ppapi