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),
     21     last_shared_memory_map_id_(0) {
     22 }
     23 
     24 HostVarTracker::~HostVarTracker() {
     25 }
     26 
     27 ArrayBufferVar* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes) {
     28   return new HostArrayBufferVar(size_in_bytes);
     29 }
     30 
     31 ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer(
     32     uint32 size_in_bytes,
     33     base::SharedMemoryHandle handle) {
     34   return new HostArrayBufferVar(size_in_bytes, handle);
     35 }
     36 
     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 
     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 
     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 
     97 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 
    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 
    117 ppapi::ResourceVar* HostVarTracker::MakeResourceVar(PP_Resource pp_resource) {
    118   return new HostResourceVar(pp_resource);
    119 }
    120 
    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 
    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 
    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 
    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