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/plugin_resource_tracker.h"
6
7#include "base/logging.h"
8#include "base/memory/singleton.h"
9#include "ppapi/proxy/plugin_dispatcher.h"
10#include "ppapi/proxy/plugin_globals.h"
11#include "ppapi/proxy/ppapi_messages.h"
12#include "ppapi/proxy/serialized_var.h"
13#include "ppapi/shared_impl/proxy_lock.h"
14#include "ppapi/shared_impl/resource.h"
15#include "ppapi/shared_impl/var.h"
16
17namespace ppapi {
18namespace proxy {
19
20PluginResourceTracker::PluginResourceTracker() : ResourceTracker(THREAD_SAFE) {
21}
22
23PluginResourceTracker::~PluginResourceTracker() {
24}
25
26PP_Resource PluginResourceTracker::PluginResourceForHostResource(
27    const HostResource& resource) const {
28  HostResourceMap::const_iterator found = host_resource_map_.find(resource);
29  if (found == host_resource_map_.end())
30    return 0;
31  return found->second;
32}
33
34PP_Resource PluginResourceTracker::AddResource(Resource* object) {
35  // If there's a HostResource, it must not be added twice.
36  DCHECK(!object->host_resource().host_resource() ||
37         (host_resource_map_.find(object->host_resource()) ==
38          host_resource_map_.end()));
39
40  PP_Resource ret = ResourceTracker::AddResource(object);
41
42  // Some resources are plugin-only, so they don't have a host resource.
43  if (object->host_resource().host_resource())
44    host_resource_map_.insert(std::make_pair(object->host_resource(), ret));
45  return ret;
46}
47
48void PluginResourceTracker::RemoveResource(Resource* object) {
49  ResourceTracker::RemoveResource(object);
50
51  if (!object->host_resource().is_null()) {
52    // The host_resource will be NULL for proxy-only resources, which we
53    // obviously don't need to tell the host about.
54    DCHECK(host_resource_map_.find(object->host_resource()) !=
55           host_resource_map_.end());
56    host_resource_map_.erase(object->host_resource());
57
58    PluginDispatcher* dispatcher =
59        PluginDispatcher::GetForInstance(object->pp_instance());
60    if (dispatcher) {
61      // The dispatcher can be NULL if the plugin held on to a resource after
62      // the instance was destroyed. In that case the browser-side resource has
63      // already been freed correctly on the browser side.
64      dispatcher->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
65          API_ID_PPB_CORE, object->host_resource()));
66    }
67  }
68}
69
70}  // namespace proxy
71}  // namespace ppapi
72