Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / host_var_tracker.cc
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 "content/renderer/pepper/host_var_tracker.h"
6
7 #include "base/logging.h"
8 #include "content/renderer/pepper/host_array_buffer_var.h"
9 #include "content/renderer/pepper/host_resource_var.h"
10 #include "content/renderer/pepper/npobject_var.h"
11 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
12 #include "ppapi/c/pp_var.h"
13
14 using ppapi::ArrayBufferVar;
15 using ppapi::NPObjectVar;
16
17 namespace content {
18
19 HostVarTracker::HostVarTracker()
20     : VarTracker(SINGLE_THREADED), last_shared_memory_map_id_(0) {}
21
22 HostVarTracker::~HostVarTracker() {}
23
24 ArrayBufferVar* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes) {
25   return new HostArrayBufferVar(size_in_bytes);
26 }
27
28 ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer(
29     uint32 size_in_bytes,
30     base::SharedMemoryHandle handle) {
31   return new HostArrayBufferVar(size_in_bytes, handle);
32 }
33
34 void HostVarTracker::AddNPObjectVar(NPObjectVar* object_var) {
35   CheckThreadingPreconditions();
36
37   InstanceMap::iterator found_instance =
38       instance_map_.find(object_var->pp_instance());
39   if (found_instance == instance_map_.end()) {
40     // Lazily create the instance map.
41     DCHECK(object_var->pp_instance() != 0);
42     found_instance =
43         instance_map_.insert(std::make_pair(
44                                  object_var->pp_instance(),
45                                  linked_ptr<NPObjectToNPObjectVarMap>(
46                                      new NPObjectToNPObjectVarMap))).first;
47   }
48   NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
49
50   DCHECK(np_object_map->find(object_var->np_object()) == np_object_map->end())
51       << "NPObjectVar already in map";
52   np_object_map->insert(std::make_pair(object_var->np_object(), object_var));
53 }
54
55 void HostVarTracker::RemoveNPObjectVar(NPObjectVar* object_var) {
56   CheckThreadingPreconditions();
57
58   InstanceMap::iterator found_instance =
59       instance_map_.find(object_var->pp_instance());
60   if (found_instance == instance_map_.end()) {
61     NOTREACHED() << "NPObjectVar has invalid instance.";
62     return;
63   }
64   NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
65
66   NPObjectToNPObjectVarMap::iterator found_object =
67       np_object_map->find(object_var->np_object());
68   if (found_object == np_object_map->end()) {
69     NOTREACHED() << "NPObjectVar not registered.";
70     return;
71   }
72   if (found_object->second != object_var) {
73     NOTREACHED() << "NPObjectVar doesn't match.";
74     return;
75   }
76   np_object_map->erase(found_object);
77 }
78
79 NPObjectVar* HostVarTracker::NPObjectVarForNPObject(PP_Instance instance,
80                                                     NPObject* np_object) {
81   CheckThreadingPreconditions();
82
83   InstanceMap::iterator found_instance = instance_map_.find(instance);
84   if (found_instance == instance_map_.end())
85     return NULL;  // No such instance.
86   NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
87
88   NPObjectToNPObjectVarMap::iterator found_object =
89       np_object_map->find(np_object);
90   if (found_object == np_object_map->end())
91     return NULL;  // No such object.
92   return found_object->second;
93 }
94
95 int HostVarTracker::GetLiveNPObjectVarsForInstance(PP_Instance instance) const {
96   CheckThreadingPreconditions();
97
98   InstanceMap::const_iterator found = instance_map_.find(instance);
99   if (found == instance_map_.end())
100     return 0;
101   return static_cast<int>(found->second->size());
102 }
103
104 PP_Var HostVarTracker::MakeResourcePPVarFromMessage(
105     PP_Instance instance,
106     const IPC::Message& creation_message,
107     int pending_renderer_id,
108     int pending_browser_id) {
109   // On the host side, the creation message is ignored when creating a resource.
110   // Therefore, a call to this function indicates a null resource. Return the
111   // resource 0.
112   return MakeResourcePPVar(0);
113 }
114
115 ppapi::ResourceVar* HostVarTracker::MakeResourceVar(PP_Resource pp_resource) {
116   return new HostResourceVar(pp_resource);
117 }
118
119 void HostVarTracker::DidDeleteInstance(PP_Instance instance) {
120   CheckThreadingPreconditions();
121
122   InstanceMap::iterator found_instance = instance_map_.find(instance);
123   if (found_instance == instance_map_.end())
124     return;  // Nothing to do.
125   NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
126
127   // Force delete all var references. ForceReleaseNPObject() will cause
128   // this object, and potentially others it references, to be removed from
129   // |np_object_map|.
130   while (!np_object_map->empty()) {
131     ForceReleaseNPObject(np_object_map->begin()->second);
132   }
133
134   // Remove the record for this instance since it should be empty.
135   DCHECK(np_object_map->empty());
136   instance_map_.erase(found_instance);
137 }
138
139 void HostVarTracker::ForceReleaseNPObject(ppapi::NPObjectVar* object_var) {
140   object_var->InstanceDeleted();
141   VarMap::iterator iter = live_vars_.find(object_var->GetExistingVarID());
142   if (iter == live_vars_.end()) {
143     NOTREACHED();
144     return;
145   }
146   iter->second.ref_count = 0;
147   DCHECK(iter->second.track_with_no_reference_count == 0);
148   DeleteObjectInfoIfNecessary(iter);
149 }
150
151 int HostVarTracker::TrackSharedMemoryHandle(PP_Instance instance,
152                                             base::SharedMemoryHandle handle,
153                                             uint32 size_in_bytes) {
154   SharedMemoryMapEntry entry;
155   entry.instance = instance;
156   entry.handle = handle;
157   entry.size_in_bytes = size_in_bytes;
158
159   // Find a free id for our map.
160   while (shared_memory_map_.find(last_shared_memory_map_id_) !=
161          shared_memory_map_.end()) {
162     ++last_shared_memory_map_id_;
163   }
164   shared_memory_map_[last_shared_memory_map_id_] = entry;
165   return last_shared_memory_map_id_;
166 }
167
168 bool HostVarTracker::StopTrackingSharedMemoryHandle(
169     int id,
170     PP_Instance instance,
171     base::SharedMemoryHandle* handle,
172     uint32* size_in_bytes) {
173   SharedMemoryMap::iterator it = shared_memory_map_.find(id);
174   if (it == shared_memory_map_.end())
175     return false;
176   if (it->second.instance != instance)
177     return false;
178
179   *handle = it->second.handle;
180   *size_in_bytes = it->second.size_in_bytes;
181   shared_memory_map_.erase(it);
182   return true;
183 }
184
185 }  // namespace content