summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/plugin_resource_tracker.cc
blob: 4abd8f74b9e792c673e8f8bc216378b7c0dd2822 (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
// Copyright (c) 2011 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/plugin_resource_tracker.h"

#include "base/logging.h"
#include "base/memory/singleton.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/serialized_var.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/shared_impl/tracker_base.h"
#include "ppapi/shared_impl/var.h"

namespace ppapi {
namespace proxy {

namespace {

// When non-NULL, this object overrides the ResourceTrackerSingleton.
PluginResourceTracker* g_resource_tracker_override = NULL;

TrackerBase* GetTrackerBase() {
  return PluginResourceTracker::GetInstance();
}

}  // namespace

PluginResourceTracker::PluginResourceTracker()
    : var_tracker_test_override_(NULL) {
#ifdef ENABLE_PEPPER_THREADING
  // Set the global proxy lock, since the plugin-side of the proxy needs to be
  // synchronized.
  ppapi::ProxyLock::Set(&proxy_lock_);
#endif
}

PluginResourceTracker::~PluginResourceTracker() {
#ifdef ENABLE_PEPPER_THREADING
  ppapi::ProxyLock::Reset();
#endif
}

// static
void PluginResourceTracker::SetInstanceForTest(PluginResourceTracker* tracker) {
  g_resource_tracker_override = tracker;
}

// static
PluginResourceTracker* PluginResourceTracker::GetInstance() {
  if (g_resource_tracker_override)
    return g_resource_tracker_override;
  return Singleton<PluginResourceTracker>::get();
}

// static
TrackerBase* PluginResourceTracker::GetTrackerBaseInstance() {
  return GetInstance();
}

PP_Resource PluginResourceTracker::PluginResourceForHostResource(
    const HostResource& resource) const {
  HostResourceMap::const_iterator found = host_resource_map_.find(resource);
  if (found == host_resource_map_.end())
    return 0;
  return found->second;
}

FunctionGroupBase* PluginResourceTracker::GetFunctionAPI(PP_Instance inst,
                                                         InterfaceID id) {
  PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(inst);
  if (dispatcher)
    return dispatcher->GetFunctionAPI(id);
  return NULL;
}

VarTracker* PluginResourceTracker::GetVarTracker() {
  return &var_tracker();
}

ResourceTracker* PluginResourceTracker::GetResourceTracker() {
  return this;
}

PP_Module PluginResourceTracker::GetModuleForInstance(PP_Instance instance) {
  // Currently proxied plugins don't use the PP_Module for anything useful.
  return 0;
}

PP_Resource PluginResourceTracker::AddResource(Resource* object) {
  PP_Resource ret = ResourceTracker::AddResource(object);

  // Some resources are plugin-only, so they don't have a host resource.
  if (object->host_resource().host_resource())
    host_resource_map_.insert(std::make_pair(object->host_resource(), ret));
  return ret;
}

void PluginResourceTracker::RemoveResource(Resource* object) {
  ResourceTracker::RemoveResource(object);

  if (!object->host_resource().is_null()) {
    // The host_resource will be NULL for proxy-only resources, which we
    // obviously don't need to tell the host about.
    DCHECK(host_resource_map_.find(object->host_resource()) !=
           host_resource_map_.end());
    host_resource_map_.erase(object->host_resource());

    PluginDispatcher* dispatcher =
        PluginDispatcher::GetForInstance(object->pp_instance());
    if (dispatcher) {
      // The dispatcher can be NULL if the plugin held on to a resource after
      // the instance was destroyed. In that case the browser-side resource has
      // already been freed correctly on the browser side.
      dispatcher->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
          INTERFACE_ID_PPB_CORE, object->host_resource()));
    }
  }
}

}  // namespace proxy
}  // namespace ppapi