146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file. 446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/browser/blob_holder.h" 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <algorithm> 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <utility> 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/logging.h" 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/public/browser/blob_handle.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/public/browser/render_process_host.h" 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace extensions { 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace { 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Address to this variable used as the user data key. 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const int kBlobHolderUserDataKey = 0; 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)BlobHolder* BlobHolder::FromRenderProcessHost( 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) content::RenderProcessHost* render_process_host) { 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(render_process_host); 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BlobHolder* existing = static_cast<BlobHolder*>( 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) render_process_host->GetUserData(&kBlobHolderUserDataKey)); 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (existing) 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return existing; 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BlobHolder* new_instance = new BlobHolder(render_process_host); 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) render_process_host->SetUserData(&kBlobHolderUserDataKey, new_instance); 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return new_instance; 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)BlobHolder::~BlobHolder() { 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void BlobHolder::HoldBlobReference(scoped_ptr<content::BlobHandle> blob) { 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!ContainsBlobHandle(blob.get())); 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string uuid = blob->GetUUID(); 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) held_blobs_.insert(make_pair(uuid, make_linked_ptr(blob.release()))); 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)BlobHolder::BlobHolder(content::RenderProcessHost* render_process_host) 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : render_process_host_(render_process_host) { 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool BlobHolder::ContainsBlobHandle(content::BlobHandle* handle) const { 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (BlobHandleMultimap::const_iterator it = held_blobs_.begin(); 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it != held_blobs_.end(); 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++it) { 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (it->second.get() == handle) 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return true; 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return false; 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void BlobHolder::DropBlobs(const std::vector<std::string>& blob_uuids) { 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (std::vector<std::string>::const_iterator uuid_it = blob_uuids.begin(); 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uuid_it != blob_uuids.end(); 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++uuid_it) { 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BlobHandleMultimap::iterator it = held_blobs_.find(*uuid_it); 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (it != held_blobs_.end()) { 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) held_blobs_.erase(it); 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DLOG(ERROR) << "Tried to release a Blob we don't have ownership to." 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) << "UUID: " << *uuid_it; 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) render_process_host_->ReceivedBadMessage(); 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace extensions 86