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 "webkit/browser/blob/blob_data_handle.h" 13 #include "webkit/browser/blob/blob_storage_context.h" 14 15 using base::UserDataAdapter; 16 using webkit_blob::BlobStorageContext; 17 18 namespace content { 19 20 namespace { 21 22 class BlobHandleImpl : public BlobHandle { 23 public: 24 BlobHandleImpl(scoped_ptr<webkit_blob::BlobDataHandle> handle) 25 : handle_(handle.Pass()) { 26 } 27 28 virtual ~BlobHandleImpl() {} 29 30 virtual std::string GetUUID() OVERRIDE { 31 return handle_->uuid(); 32 } 33 34 private: 35 scoped_ptr<webkit_blob::BlobDataHandle> handle_; 36 }; 37 38 } // namespace 39 40 static const char* kBlobStorageContextKeyName = "content_blob_storage_context"; 41 42 ChromeBlobStorageContext::ChromeBlobStorageContext() {} 43 44 ChromeBlobStorageContext* 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 64 void ChromeBlobStorageContext::InitializeOnIOThread() { 65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 66 context_.reset(new BlobStorageContext()); 67 } 68 69 scoped_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<webkit_blob::BlobData> blob_data = 75 new webkit_blob::BlobData(uuid); 76 blob_data->AppendData(data, length); 77 78 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle = 79 context_->AddFinishedBlob(blob_data.get()); 80 if (!blob_data_handle) 81 return scoped_ptr<BlobHandle>(); 82 83 scoped_ptr<BlobHandle> blob_handle( 84 new BlobHandleImpl(blob_data_handle.Pass())); 85 return blob_handle.Pass(); 86 } 87 88 ChromeBlobStorageContext::~ChromeBlobStorageContext() {} 89 90 void ChromeBlobStorageContext::DeleteOnCorrectThread() const { 91 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO) && 92 !BrowserThread::CurrentlyOn(BrowserThread::IO)) { 93 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this); 94 return; 95 } 96 delete this; 97 } 98 99 } // namespace content 100