blob: 8553d0266d2d8b6338a176f4e9d9ce9d7675fa85 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_storage_registry.h"
#include "storage/browser/blob/internal_blob_data.h"
#include "storage/browser/storage_browser_export.h"
#include "storage/common/blob_storage/blob_storage_constants.h"
#include "storage/common/data_element.h"
class GURL;
namespace base {
class FilePath;
class Time;
namespace content {
class BlobDispatcherHost;
class BlobDispatcherHostTest;
namespace storage {
class BlobDataBuilder;
class BlobDataItem;
class BlobDataSnapshot;
class ShareableBlobDataItem;
// This class handles the logistics of blob Storage within the browser process,
// and maintains a mapping from blob uuid to the data. The class is single
// threaded and should only be used on the IO thread.
// In chromium, there is one instance per profile.
class STORAGE_EXPORT BlobStorageContext
: public base::SupportsWeakPtr<BlobStorageContext> {
std::unique_ptr<BlobDataHandle> GetBlobDataFromUUID(const std::string& uuid);
std::unique_ptr<BlobDataHandle> GetBlobDataFromPublicURL(const GURL& url);
// Useful for coining blobs from within the browser process. If the
// blob cannot be added due to memory consumption, returns NULL.
// A builder should not be used twice to create blobs, as the internal
// resources are refcounted instead of copied for memory efficiency.
// To cleanly use a builder multiple times, please call Clone() on the
// builder, or even better for memory savings, clear the builder and append
// the previously constructed blob.
std::unique_ptr<BlobDataHandle> AddFinishedBlob(
const BlobDataBuilder& builder);
// Deprecated, use const ref version above.
std::unique_ptr<BlobDataHandle> AddFinishedBlob(
const BlobDataBuilder* builder);
// Useful for coining blob urls from within the browser process.
bool RegisterPublicBlobURL(const GURL& url, const std::string& uuid);
void RevokePublicBlobURL(const GURL& url);
size_t memory_usage() const { return memory_usage_; }
size_t blob_count() const { return registry_.blob_count(); }
size_t memory_available() const {
return kBlobStorageMaxMemoryUsage - memory_usage_;
const BlobStorageRegistry& registry() { return registry_; }
using BlobRegistryEntry = BlobStorageRegistry::Entry;
using BlobConstructedCallback = BlobStorageRegistry::BlobConstructedCallback;
friend class content::BlobDispatcherHost;
friend class BlobAsyncBuilderHost;
friend class BlobAsyncBuilderHostTest;
friend class BlobDataHandle;
friend class BlobDataHandle::BlobDataHandleShared;
friend class BlobReaderTest;
FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, HandleBeforeAsyncCancel);
FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, ReadFromIncompleteBlob);
friend class BlobStorageContextTest;
FRIEND_TEST_ALL_PREFIXES(BlobStorageContextTest, IncrementDecrementRef);
FRIEND_TEST_ALL_PREFIXES(BlobStorageContextTest, OnCancelBuildingBlob);
FRIEND_TEST_ALL_PREFIXES(BlobStorageContextTest, PublicBlobUrls);
friend class ViewBlobInternalsJob;
// CompletePendingBlob or CancelPendingBlob should be called after this.
void CreatePendingBlob(const std::string& uuid,
const std::string& content_type,
const std::string& content_disposition);
// This includes resolving blob references in the builder. This will run the
// callbacks given in RunOnConstructionComplete.
void CompletePendingBlob(const BlobDataBuilder& external_builder);
// This will run the callbacks given in RunOnConstructionComplete.
void CancelPendingBlob(const std::string& uuid,
IPCBlobCreationCancelCode reason);
void IncrementBlobRefCount(const std::string& uuid);
void DecrementBlobRefCount(const std::string& uuid);
// Methods called by BlobDataHandle:
// This will return an empty snapshot until the blob is complete.
// TODO(dmurph): After we make the snapshot method in BlobHandle private, then
// make this DCHECK on the blob not being complete.
std::unique_ptr<BlobDataSnapshot> CreateSnapshot(const std::string& uuid);
bool IsBroken(const std::string& uuid) const;
bool IsBeingBuilt(const std::string& uuid) const;
// Runs |done| when construction completes, with true if it was successful,
// and false if there was an error, which is reported in the second argument
// of the callback.
void RunOnConstructionComplete(const std::string& uuid,
const BlobConstructedCallback& done);
// Appends the given blob item to the blob builder. The new blob
// retains ownership of data_item if applicable, and returns false if there
// was an error and pouplates the error_code. We can either have an error of:
// OUT_OF_MEMORY: We are out of memory to store this blob.
// REFERENCED_BLOB_BROKEN: One of the referenced blobs is broken.
bool AppendAllocatedBlobItem(const std::string& target_blob_uuid,
scoped_refptr<BlobDataItem> data_item,
InternalBlobData::Builder* target_blob_data,
IPCBlobCreationCancelCode* error_code);
// Allocates a shareable blob data item, with blob references resolved. If
// there isn't enough memory, then a nullptr is returned.
scoped_refptr<ShareableBlobDataItem> AllocateShareableBlobDataItem(
const std::string& target_blob_uuid,
scoped_refptr<BlobDataItem> data_item);
// Deconstructs the blob and appends it's contents to the target blob. Items
// are shared if possible, and copied if the given offset and length
// have to split an item.
bool AppendBlob(const std::string& target_blob_uuid,
const InternalBlobData& blob,
uint64_t offset,
uint64_t length,
InternalBlobData::Builder* target_blob_data);
BlobStorageRegistry registry_;
// Used to keep track of how much memory is being utilized for blob data,
// we count only the items of TYPE_DATA which are held in memory and not
// items of TYPE_FILE.
size_t memory_usage_;
} // namespace storage