Home | History | Annotate | Download | only in fileapi
      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