Home | History | Annotate | Download | only in pepper
      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
    186