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