| Index: ppapi/proxy/plugin_resource_tracker.cc | 
| =================================================================== | 
| --- ppapi/proxy/plugin_resource_tracker.cc	(revision 72840) | 
| +++ ppapi/proxy/plugin_resource_tracker.cc	(working copy) | 
| @@ -14,6 +14,13 @@ | 
| namespace pp { | 
| namespace proxy { | 
|  | 
| +namespace { | 
| + | 
| +// When non-NULL, this object overrides the ResourceTrackerSingleton. | 
| +PluginResourceTracker* g_resource_tracker_override = NULL; | 
| + | 
| +}  // namespace | 
| + | 
| PluginResourceTracker::ResourceInfo::ResourceInfo() : ref_count(0) { | 
| } | 
|  | 
| @@ -39,14 +46,24 @@ | 
| return *this; | 
| } | 
|  | 
| -PluginResourceTracker::PluginResourceTracker() { | 
| +// Start counting resources at a high number to avoid collisions with vars (to | 
| +// help debugging). | 
| +PluginResourceTracker::PluginResourceTracker() | 
| +    : last_resource_id_(0x00100000) { | 
| } | 
|  | 
| PluginResourceTracker::~PluginResourceTracker() { | 
| } | 
|  | 
| // static | 
| +void PluginResourceTracker::SetInstanceForTest(PluginResourceTracker* tracker) { | 
| +  g_resource_tracker_override = tracker; | 
| +} | 
| + | 
| +// static | 
| PluginResourceTracker* PluginResourceTracker::GetInstance() { | 
| +  if (g_resource_tracker_override) | 
| +    return g_resource_tracker_override; | 
| return Singleton<PluginResourceTracker>::get(); | 
| } | 
|  | 
| @@ -58,37 +75,41 @@ | 
| return found->second.resource.get(); | 
| } | 
|  | 
| -void PluginResourceTracker::AddResource(PP_Resource pp_resource, | 
| -                                        linked_ptr<PluginResource> object) { | 
| -  DCHECK(resource_map_.find(pp_resource) == resource_map_.end()); | 
| -  resource_map_[pp_resource] = ResourceInfo(1, object); | 
| +PP_Resource PluginResourceTracker::AddResource( | 
| +    linked_ptr<PluginResource> object) { | 
| +  if (object->host_resource().is_null()) { | 
| +    // Prevent adding null resources or GetResourceObject(0) will return a | 
| +    // valid pointer! | 
| +    NOTREACHED(); | 
| +    return 0; | 
| +  } | 
| + | 
| +  PP_Resource plugin_resource = ++last_resource_id_; | 
| +  DCHECK(resource_map_.find(plugin_resource) == resource_map_.end()); | 
| +  resource_map_[plugin_resource] = ResourceInfo(1, object); | 
| +  host_resource_map_[object->host_resource()] = plugin_resource; | 
| +  return plugin_resource; | 
| } | 
|  | 
| void PluginResourceTracker::AddRefResource(PP_Resource resource) { | 
| -  resource_map_[resource].ref_count++; | 
| +  ResourceMap::iterator found = resource_map_.find(resource); | 
| +  if (found == resource_map_.end()) { | 
| +    NOTREACHED(); | 
| +    return; | 
| +  } | 
| +  found->second.ref_count++; | 
| } | 
|  | 
| void PluginResourceTracker::ReleaseResource(PP_Resource resource) { | 
| ReleasePluginResourceRef(resource, true); | 
| } | 
|  | 
| -bool PluginResourceTracker::PreparePreviouslyTrackedResource( | 
| -    PP_Resource resource) { | 
| -  ResourceMap::iterator found = resource_map_.find(resource); | 
| -  if (found == resource_map_.end()) | 
| -    return false;  // We've not seen this resource before. | 
| - | 
| -  // We have already seen this resource and the caller wants the plugin to | 
| -  // have one more ref to the object (this function is called when retuning | 
| -  // a resource). | 
| -  // | 
| -  // This is like the PluginVarTracker::ReceiveObjectPassRef. We do an AddRef | 
| -  // in the plugin for the additional ref, and then a Release in the renderer | 
| -  // because the code in the renderer addrefed on behalf of the caller. | 
| -  found->second.ref_count++; | 
| - | 
| -  SendReleaseResourceToHost(resource, found->second.resource.get()); | 
| -  return true; | 
| +PP_Resource PluginResourceTracker::PluginResourceForHostResource( | 
| +    const HostResource& resource) const { | 
| +  HostResourceMap::const_iterator found = host_resource_map_.find(resource); | 
| +  if (found == host_resource_map_.end()) | 
| +    return 0; | 
| +  return found->second; | 
| } | 
|  | 
| void PluginResourceTracker::ReleasePluginResourceRef( | 
| @@ -99,8 +120,10 @@ | 
| return; | 
| found->second.ref_count--; | 
| if (found->second.ref_count == 0) { | 
| +    PluginResource* plugin_resource = found->second.resource.get(); | 
| if (notify_browser_on_release) | 
| -      SendReleaseResourceToHost(resource, found->second.resource.get()); | 
| +      SendReleaseResourceToHost(resource, plugin_resource); | 
| +    host_resource_map_.erase(plugin_resource->host_resource()); | 
| resource_map_.erase(found); | 
| } | 
| } | 
| @@ -112,7 +135,7 @@ | 
| PluginDispatcher::GetForInstance(resource->instance()); | 
| if (dispatcher) { | 
| dispatcher->Send(new PpapiHostMsg_PPBCore_ReleaseResource( | 
| -        INTERFACE_ID_PPB_CORE, resource_id)); | 
| +        INTERFACE_ID_PPB_CORE, resource->host_resource())); | 
| } else { | 
| NOTREACHED(); | 
| } | 
|  |