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/browser/fileapi/chrome_blob_storage_context.h" 6 7#include "base/bind.h" 8#include "base/guid.h" 9#include "content/public/browser/blob_handle.h" 10#include "content/public/browser/browser_context.h" 11#include "content/public/browser/browser_thread.h" 12#include "storage/browser/blob/blob_data_handle.h" 13#include "storage/browser/blob/blob_storage_context.h" 14 15using base::UserDataAdapter; 16using storage::BlobStorageContext; 17 18namespace content { 19 20namespace { 21 22const char kBlobStorageContextKeyName[] = "content_blob_storage_context"; 23 24class BlobHandleImpl : public BlobHandle { 25 public: 26 explicit BlobHandleImpl(scoped_ptr<storage::BlobDataHandle> handle) 27 : handle_(handle.Pass()) { 28 } 29 30 virtual ~BlobHandleImpl() {} 31 32 virtual std::string GetUUID() OVERRIDE { 33 return handle_->uuid(); 34 } 35 36 private: 37 scoped_ptr<storage::BlobDataHandle> handle_; 38}; 39 40} // namespace 41 42ChromeBlobStorageContext::ChromeBlobStorageContext() {} 43 44ChromeBlobStorageContext* ChromeBlobStorageContext::GetFor( 45 BrowserContext* context) { 46 if (!context->GetUserData(kBlobStorageContextKeyName)) { 47 scoped_refptr<ChromeBlobStorageContext> blob = 48 new ChromeBlobStorageContext(); 49 context->SetUserData( 50 kBlobStorageContextKeyName, 51 new UserDataAdapter<ChromeBlobStorageContext>(blob.get())); 52 // Check first to avoid memory leak in unittests. 53 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { 54 BrowserThread::PostTask( 55 BrowserThread::IO, FROM_HERE, 56 base::Bind(&ChromeBlobStorageContext::InitializeOnIOThread, blob)); 57 } 58 } 59 60 return UserDataAdapter<ChromeBlobStorageContext>::Get( 61 context, kBlobStorageContextKeyName); 62} 63 64void ChromeBlobStorageContext::InitializeOnIOThread() { 65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 66 context_.reset(new BlobStorageContext()); 67} 68 69scoped_ptr<BlobHandle> ChromeBlobStorageContext::CreateMemoryBackedBlob( 70 const char* data, size_t length) { 71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 72 73 std::string uuid(base::GenerateGUID()); 74 scoped_refptr<storage::BlobData> blob_data = new storage::BlobData(uuid); 75 blob_data->AppendData(data, length); 76 77 scoped_ptr<storage::BlobDataHandle> blob_data_handle = 78 context_->AddFinishedBlob(blob_data.get()); 79 if (!blob_data_handle) 80 return scoped_ptr<BlobHandle>(); 81 82 scoped_ptr<BlobHandle> blob_handle( 83 new BlobHandleImpl(blob_data_handle.Pass())); 84 return blob_handle.Pass(); 85} 86 87ChromeBlobStorageContext::~ChromeBlobStorageContext() {} 88 89void ChromeBlobStorageContext::DeleteOnCorrectThread() const { 90 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO) && 91 !BrowserThread::CurrentlyOn(BrowserThread::IO)) { 92 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this); 93 return; 94 } 95 delete this; 96} 97 98} // namespace content 99