diff options
Diffstat (limited to 'chromium/storage')
130 files changed, 2012 insertions, 1460 deletions
diff --git a/chromium/storage/browser/BUILD.gn b/chromium/storage/browser/BUILD.gn index 1b96575fceb..68027c0854e 100644 --- a/chromium/storage/browser/BUILD.gn +++ b/chromium/storage/browser/BUILD.gn @@ -8,8 +8,8 @@ component("browser") { sources = [ "blob/blob_async_builder_host.cc", "blob/blob_async_builder_host.h", - "blob/blob_async_transport_strategy.cc", - "blob/blob_async_transport_strategy.h", + "blob/blob_async_transport_request_builder.cc", + "blob/blob_async_transport_request_builder.h", "blob/blob_data_builder.cc", "blob/blob_data_builder.h", "blob/blob_data_handle.cc", @@ -188,13 +188,15 @@ component("browser") { "//build/config/compiler:wexit_time_destructors", ] + public_deps = [ + "//storage/common", + ] deps = [ "//base", "//base:i18n", "//base/third_party/dynamic_annotations", "//net", "//sql", - "//storage/common", "//third_party/leveldatabase", "//third_party/sqlite", "//url", diff --git a/chromium/storage/browser/blob/blob_async_builder_host.cc b/chromium/storage/browser/blob/blob_async_builder_host.cc index 6d4432748c3..c30b3833e90 100644 --- a/chromium/storage/browser/blob/blob_async_builder_host.cc +++ b/chromium/storage/browser/blob/blob_async_builder_host.cc @@ -7,117 +7,226 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <utility> +#include "base/bind.h" +#include "base/memory/ptr_util.h" #include "base/memory/shared_memory.h" +#include "storage/browser/blob/blob_data_handle.h" +#include "storage/browser/blob/blob_storage_context.h" namespace storage { +namespace { -using MemoryItemRequest = BlobAsyncTransportStrategy::RendererMemoryItemRequest; +bool CalculateBlobMemorySize(const std::vector<DataElement>& elements, + size_t* shortcut_bytes, + uint64_t* total_bytes) { + DCHECK(shortcut_bytes); + DCHECK(total_bytes); + base::CheckedNumeric<uint64_t> total_size_checked = 0; + base::CheckedNumeric<size_t> shortcut_size_checked = 0; + for (const auto& e : elements) { + if (e.type() == DataElement::TYPE_BYTES) { + total_size_checked += e.length(); + shortcut_size_checked += e.length(); + } else if (e.type() == DataElement::TYPE_BYTES_DESCRIPTION) { + total_size_checked += e.length(); + } else { + continue; + } + if (!total_size_checked.IsValid() || !shortcut_size_checked.IsValid()) { + return false; + } + } + *shortcut_bytes = shortcut_size_checked.ValueOrDie(); + *total_bytes = total_size_checked.ValueOrDie(); + return true; +} + +IPCBlobCreationCancelCode ConvertReferencedBlobErrorToConstructingError( + IPCBlobCreationCancelCode referenced_blob_error) { + switch (referenced_blob_error) { + // For most cases we propagate the error. + case IPCBlobCreationCancelCode::FILE_WRITE_FAILED: + case IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT: + case IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN: + case IPCBlobCreationCancelCode::OUT_OF_MEMORY: + return referenced_blob_error; + // Others we report that the referenced blob is broken, as we don't know + // why (the BLOB_DEREFERENCED_WHILE_BUILDING should never happen, as we hold + // onto the reference of the blobs we're using). + case IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING: + DCHECK(false) << "Referenced blob should never be dereferenced while we " + << "are depending on it, as our system holds a handle."; + case IPCBlobCreationCancelCode::UNKNOWN: + return IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN; + } + NOTREACHED(); + return IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN; +} + +} // namespace -BlobAsyncBuilderHost::BlobBuildingState::BlobBuildingState() - : next_request(0), - num_fulfilled_requests(0), - num_shared_memory_requests(0), - current_shared_memory_handle_index(0) {} +using MemoryItemRequest = + BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest; + +BlobAsyncBuilderHost::BlobBuildingState::BlobBuildingState( + const std::string& uuid, + std::set<std::string> referenced_blob_uuids, + std::vector<std::unique_ptr<BlobDataHandle>>* referenced_blob_handles) + : data_builder(uuid), + referenced_blob_uuids(referenced_blob_uuids), + referenced_blob_handles(std::move(*referenced_blob_handles)) {} BlobAsyncBuilderHost::BlobBuildingState::~BlobBuildingState() {} -BlobAsyncBuilderHost::BlobAsyncBuilderHost() {} +BlobAsyncBuilderHost::BlobAsyncBuilderHost() : ptr_factory_(this) {} BlobAsyncBuilderHost::~BlobAsyncBuilderHost() {} -bool BlobAsyncBuilderHost::StartBuildingBlob( +BlobTransportResult BlobAsyncBuilderHost::RegisterBlobUUID( const std::string& uuid, - const std::string& type, - const std::vector<DataElement>& descriptions, - size_t memory_available, - const base::Callback<void(const std::vector<storage::BlobItemBytesRequest>&, - const std::vector<base::SharedMemoryHandle>&, - const std::vector<uint64_t>&)>& request_memory, - const base::Callback<void(const BlobDataBuilder&)>& done, - const base::Callback<void(IPCBlobCreationCancelCode)>& cancel) { + const std::string& content_type, + const std::string& content_disposition, + const std::set<std::string>& referenced_blob_uuids, + BlobStorageContext* context) { if (async_blob_map_.find(uuid) != async_blob_map_.end()) - return false; - if (BlobAsyncTransportStrategy::ShouldBeShortcut(descriptions, - memory_available)) { - // We have enough memory, and all the data is here, so we use the shortcut - // method and populate the old way. - BlobDataBuilder builder(uuid); - builder.set_content_type(type); - for (const DataElement& element : descriptions) { - builder.AppendIPCDataElement(element); + return BlobTransportResult::BAD_IPC; + if (referenced_blob_uuids.find(uuid) != referenced_blob_uuids.end()) + return BlobTransportResult::BAD_IPC; + context->CreatePendingBlob(uuid, content_type, content_disposition); + std::vector<std::unique_ptr<BlobDataHandle>> handles; + for (const std::string& referenced_uuid : referenced_blob_uuids) { + std::unique_ptr<BlobDataHandle> handle = + context->GetBlobDataFromUUID(referenced_uuid); + if (!handle || handle->IsBroken()) { + // We cancel the blob right away, and don't bother storing our state. + context->CancelPendingBlob( + uuid, IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN); + return BlobTransportResult::CANCEL_REFERENCED_BLOB_BROKEN; } - done.Run(builder); - return true; + handles.emplace_back(std::move(handle)); } + async_blob_map_[uuid] = base::WrapUnique( + new BlobBuildingState(uuid, referenced_blob_uuids, &handles)); + return BlobTransportResult::DONE; +} - scoped_ptr<BlobBuildingState> state(new BlobBuildingState()); - BlobBuildingState* state_ptr = state.get(); - async_blob_map_[uuid] = std::move(state); - state_ptr->type = type; +BlobTransportResult BlobAsyncBuilderHost::StartBuildingBlob( + const std::string& uuid, + const std::vector<DataElement>& elements, + size_t memory_available, + BlobStorageContext* context, + const RequestMemoryCallback& request_memory) { + DCHECK(context); + DCHECK(async_blob_map_.find(uuid) != async_blob_map_.end()); + + // Step 1: Get the sizes. + size_t shortcut_memory_size_bytes = 0; + uint64_t total_memory_size_bytes = 0; + if (!CalculateBlobMemorySize(elements, &shortcut_memory_size_bytes, + &total_memory_size_bytes)) { + CancelBuildingBlob(uuid, IPCBlobCreationCancelCode::UNKNOWN, context); + return BlobTransportResult::BAD_IPC; + } + + // Step 2: Check if we have enough memory to store the blob. + if (total_memory_size_bytes > memory_available) { + CancelBuildingBlob(uuid, IPCBlobCreationCancelCode::OUT_OF_MEMORY, context); + return BlobTransportResult::CANCEL_MEMORY_FULL; + } + + // From here on, we know we can fit the blob in memory. + BlobBuildingState* state_ptr = async_blob_map_[uuid].get(); + if (!state_ptr->request_builder.requests().empty()) { + // Check that we're not a duplicate call. + return BlobTransportResult::BAD_IPC; + } state_ptr->request_memory_callback = request_memory; - state_ptr->done_callback = done; - state_ptr->cancel_callback = cancel; - - // We are currently only operating in 'no disk' mode. This will change in - // future patches to enable disk storage. - // Since we don't have a disk yet, we put 0 for disk_space_left. - state_ptr->transport_strategy.Initialize( - max_ipc_memory_size_, max_shared_memory_size_, max_file_size_, - 0 /* disk_space_left */, memory_available, uuid, descriptions); - - switch (state_ptr->transport_strategy.error()) { - case BlobAsyncTransportStrategy::ERROR_TOO_LARGE: - // Cancel cleanly, we're out of memory. - CancelAndCleanup(uuid, IPCBlobCreationCancelCode::OUT_OF_MEMORY); - return true; - case BlobAsyncTransportStrategy::ERROR_INVALID_PARAMS: - // Bad IPC, so we ignore and clean up. - VLOG(1) << "Error initializing transport strategy: " - << state_ptr->transport_strategy.error(); - async_blob_map_.erase(async_blob_map_.find(uuid)); - return false; - case BlobAsyncTransportStrategy::ERROR_NONE: - ContinueBlobMemoryRequests(uuid); - return true; + + // Step 3: Check to make sure the referenced blob information we received + // earlier is correct: + std::set<std::string> extracted_blob_uuids; + for (const DataElement& e : elements) { + if (e.type() == DataElement::TYPE_BLOB) { + extracted_blob_uuids.insert(e.blob_uuid()); + // We can't depend on ourselves. + if (e.blob_uuid() == uuid) { + CancelBuildingBlob(uuid, IPCBlobCreationCancelCode::UNKNOWN, context); + return BlobTransportResult::BAD_IPC; + } + } + } + if (extracted_blob_uuids != state_ptr->referenced_blob_uuids) { + CancelBuildingBlob(uuid, IPCBlobCreationCancelCode::UNKNOWN, context); + return BlobTransportResult::BAD_IPC; + } + + // Step 4: Decide if we're using the shortcut method. This will also catch + // the case where we don't have any memory items. + if (shortcut_memory_size_bytes == total_memory_size_bytes && + shortcut_memory_size_bytes <= memory_available) { + for (const DataElement& e : elements) { + state_ptr->data_builder.AppendIPCDataElement(e); + } + FinishBuildingBlob(state_ptr, context); + return BlobTransportResult::DONE; + } + + // From here on, we know the blob's size is less than |memory_available|, + // so we know we're < max(size_t). + // Step 5: Decide if we're using shared memory. + if (total_memory_size_bytes > max_ipc_memory_size_) { + state_ptr->request_builder.InitializeForSharedMemoryRequests( + max_shared_memory_size_, total_memory_size_bytes, elements, + &(state_ptr->data_builder)); + } else { + // Step 6: We can fit in IPC. + state_ptr->request_builder.InitializeForIPCRequests( + max_ipc_memory_size_, total_memory_size_bytes, elements, + &(state_ptr->data_builder)); } - return false; + // We initialize our requests received state now that they are populated. + state_ptr->request_received.resize( + state_ptr->request_builder.requests().size(), false); + return ContinueBlobMemoryRequests(uuid, context); } -bool BlobAsyncBuilderHost::OnMemoryResponses( +BlobTransportResult BlobAsyncBuilderHost::OnMemoryResponses( const std::string& uuid, - const std::vector<BlobItemBytesResponse>& responses) { - if (responses.empty()) { - return false; - } + const std::vector<BlobItemBytesResponse>& responses, + BlobStorageContext* context) { AsyncBlobMap::const_iterator state_it = async_blob_map_.find(uuid); if (state_it == async_blob_map_.end()) { - // There's a possibility that we had a shared memory error, and there were - // still responses in flight. So we don't fail here, we just ignore. DVLOG(1) << "Could not find blob " << uuid; - return true; + return BlobTransportResult::BAD_IPC; + } + if (responses.empty()) { + CancelBuildingBlob(uuid, IPCBlobCreationCancelCode::UNKNOWN, context); + return BlobTransportResult::BAD_IPC; } BlobAsyncBuilderHost::BlobBuildingState* state = state_it->second.get(); - BlobAsyncTransportStrategy& strategy = state->transport_strategy; - bool invalid_ipc = false; - bool memory_error = false; - const auto& requests = strategy.requests(); + BlobAsyncTransportRequestBuilder& request_builder = state->request_builder; + const auto& requests = request_builder.requests(); for (const BlobItemBytesResponse& response : responses) { if (response.request_number >= requests.size()) { // Bad IPC, so we delete our record and ignore. DVLOG(1) << "Invalid request number " << response.request_number; - async_blob_map_.erase(state_it); - return false; + CancelBuildingBlob(uuid, IPCBlobCreationCancelCode::UNKNOWN, context); + return BlobTransportResult::BAD_IPC; } + DCHECK_LT(response.request_number, state->request_received.size()); const MemoryItemRequest& request = requests[response.request_number]; - if (request.received) { + if (state->request_received[response.request_number]) { // Bad IPC, so we delete our record. DVLOG(1) << "Already received response for that request."; - async_blob_map_.erase(state_it); - return false; + CancelBuildingBlob(uuid, IPCBlobCreationCancelCode::UNKNOWN, context); + return BlobTransportResult::BAD_IPC; } - strategy.MarkRequestAsReceived(response.request_number); + state->request_received[response.request_number] = true; + bool invalid_ipc = false; + bool memory_error = false; switch (request.message.transport_strategy) { case IPCBlobItemRequestStrategy::IPC: if (response.inline_data.size() < request.message.size) { @@ -126,7 +235,7 @@ bool BlobAsyncBuilderHost::OnMemoryResponses( invalid_ipc = true; break; } - invalid_ipc = !strategy.blob_builder()->PopulateFutureData( + invalid_ipc = !state->data_builder.PopulateFutureData( request.browser_item_index, &response.inline_data[0], request.browser_item_offset, request.message.size); break; @@ -142,8 +251,8 @@ bool BlobAsyncBuilderHost::OnMemoryResponses( // whole thing in this group of responses. Another option is to use // MapAt, remove the mapped boolean, and then exclude the // handle_offset below. - size_t handle_size = strategy.handle_sizes().at( - state->current_shared_memory_handle_index); + size_t handle_size = request_builder.shared_memory_sizes() + [state->current_shared_memory_handle_index]; if (!state->shared_memory_block->Map(handle_size)) { DVLOG(1) << "Unable to map memory to size " << handle_size; memory_error = true; @@ -151,7 +260,7 @@ bool BlobAsyncBuilderHost::OnMemoryResponses( } } - invalid_ipc = !strategy.blob_builder()->PopulateFutureData( + invalid_ipc = !state->data_builder.PopulateFutureData( request.browser_item_index, static_cast<const char*>(state->shared_memory_block->memory()) + request.message.handle_offset, @@ -165,46 +274,84 @@ bool BlobAsyncBuilderHost::OnMemoryResponses( } if (invalid_ipc) { // Bad IPC, so we delete our record and return false. - async_blob_map_.erase(state_it); - return false; + CancelBuildingBlob(uuid, IPCBlobCreationCancelCode::UNKNOWN, context); + return BlobTransportResult::BAD_IPC; } if (memory_error) { DVLOG(1) << "Shared memory error."; - CancelAndCleanup(uuid, IPCBlobCreationCancelCode::OUT_OF_MEMORY); - return true; + CancelBuildingBlob(uuid, IPCBlobCreationCancelCode::OUT_OF_MEMORY, + context); + return BlobTransportResult::CANCEL_MEMORY_FULL; } state->num_fulfilled_requests++; } - ContinueBlobMemoryRequests(uuid); - return true; + return ContinueBlobMemoryRequests(uuid, context); } -void BlobAsyncBuilderHost::StopBuildingBlob(const std::string& uuid) { - async_blob_map_.erase(async_blob_map_.find(uuid)); +void BlobAsyncBuilderHost::CancelBuildingBlob(const std::string& uuid, + IPCBlobCreationCancelCode code, + BlobStorageContext* context) { + DCHECK(context); + auto state_it = async_blob_map_.find(uuid); + if (state_it == async_blob_map_.end()) { + return; + } + // We can have the blob dereferenced by the renderer, but have it still being + // 'built'. In this case, it's destructed in the context, but we still have + // it in our map. Hence we make sure the context has the entry before + // calling cancel. + if (context->registry().HasEntry(uuid)) + context->CancelPendingBlob(uuid, code); + async_blob_map_.erase(state_it); +} + +void BlobAsyncBuilderHost::CancelAll(BlobStorageContext* context) { + DCHECK(context); + // If the blob still exists in the context (and is being built), then we know + // that someone else is expecting our blob, and we need to cancel it to let + // the dependency know it's gone. + std::vector<std::unique_ptr<BlobDataHandle>> referenced_pending_blobs; + for (const auto& uuid_state_pair : async_blob_map_) { + if (context->IsBeingBuilt(uuid_state_pair.first)) { + referenced_pending_blobs.emplace_back( + context->GetBlobDataFromUUID(uuid_state_pair.first)); + } + } + // We clear the map before canceling them to prevent any strange reentry into + // our class (see ReferencedBlobFinished) if any blobs were waiting for others + // to construct. + async_blob_map_.clear(); + for (const std::unique_ptr<BlobDataHandle>& handle : + referenced_pending_blobs) { + context->CancelPendingBlob( + handle->uuid(), IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT); + } } -void BlobAsyncBuilderHost::ContinueBlobMemoryRequests(const std::string& uuid) { +BlobTransportResult BlobAsyncBuilderHost::ContinueBlobMemoryRequests( + const std::string& uuid, + BlobStorageContext* context) { AsyncBlobMap::const_iterator state_it = async_blob_map_.find(uuid); DCHECK(state_it != async_blob_map_.end()); BlobAsyncBuilderHost::BlobBuildingState* state = state_it->second.get(); - const std::vector<MemoryItemRequest>& requests = - state->transport_strategy.requests(); - BlobAsyncTransportStrategy& strategy = state->transport_strategy; + BlobAsyncTransportRequestBuilder& request_builder = state->request_builder; + const std::vector<MemoryItemRequest>& requests = request_builder.requests(); size_t num_requests = requests.size(); if (state->num_fulfilled_requests == num_requests) { - DoneAndCleanup(uuid); - return; + FinishBuildingBlob(state, context); + return BlobTransportResult::DONE; } DCHECK_LT(state->num_fulfilled_requests, num_requests); if (state->next_request == num_requests) { // We are still waiting on other requests to come back. - return; + return BlobTransportResult::PENDING_RESPONSES; } - std::vector<BlobItemBytesRequest> byte_requests; - std::vector<base::SharedMemoryHandle> shared_memory; - std::vector<uint64_t> files; + std::unique_ptr<std::vector<BlobItemBytesRequest>> byte_requests( + new std::vector<BlobItemBytesRequest>()); + std::unique_ptr<std::vector<base::SharedMemoryHandle>> shared_memory( + new std::vector<base::SharedMemoryHandle>()); for (; state->next_request < num_requests; ++state->next_request) { const MemoryItemRequest& request = requests[state->next_request]; @@ -213,7 +360,7 @@ void BlobAsyncBuilderHost::ContinueBlobMemoryRequests(const std::string& uuid) { bool using_shared_memory_handle = state->num_shared_memory_requests > 0; switch (request.message.transport_strategy) { case IPCBlobItemRequestStrategy::IPC: - byte_requests.push_back(request.message); + byte_requests->push_back(request.message); break; case IPCBlobItemRequestStrategy::SHARED_MEMORY: if (using_shared_memory_handle && @@ -230,18 +377,19 @@ void BlobAsyncBuilderHost::ContinueBlobMemoryRequests(const std::string& uuid) { if (!state->shared_memory_block) { state->shared_memory_block.reset(new base::SharedMemory()); - size_t size = strategy.handle_sizes()[request.message.handle_index]; + size_t size = + request_builder + .shared_memory_sizes()[request.message.handle_index]; if (!state->shared_memory_block->CreateAnonymous(size)) { DVLOG(1) << "Unable to allocate shared memory for blob transfer."; - CancelAndCleanup(uuid, IPCBlobCreationCancelCode::OUT_OF_MEMORY); - return; + return BlobTransportResult::CANCEL_MEMORY_FULL; } } - shared_memory.push_back(state->shared_memory_block->handle()); - byte_requests.push_back(request.message); + shared_memory->push_back(state->shared_memory_block->handle()); + byte_requests->push_back(request.message); // Since we are only using one handle at a time, transform our handle // index correctly back to 0. - byte_requests.back().handle_index = 0; + byte_requests->back().handle_index = 0; break; case IPCBlobItemRequestStrategy::FILE: case IPCBlobItemRequestStrategy::UNKNOWN: @@ -252,25 +400,66 @@ void BlobAsyncBuilderHost::ContinueBlobMemoryRequests(const std::string& uuid) { break; } } - DCHECK(!requests.empty()); - state->request_memory_callback.Run(byte_requests, shared_memory, files); + state->request_memory_callback.Run( + std::move(byte_requests), std::move(shared_memory), + base::WrapUnique(new std::vector<base::File>())); + return BlobTransportResult::PENDING_RESPONSES; } -void BlobAsyncBuilderHost::CancelAndCleanup(const std::string& uuid, - IPCBlobCreationCancelCode code) { - scoped_ptr<BlobBuildingState> state = std::move(async_blob_map_[uuid]); - async_blob_map_.erase(uuid); - state->cancel_callback.Run(code); +void BlobAsyncBuilderHost::ReferencedBlobFinished( + const std::string& owning_blob_uuid, + base::WeakPtr<BlobStorageContext> context, + bool construction_success, + IPCBlobCreationCancelCode reason) { + if (!context) { + return; + } + auto state_it = async_blob_map_.find(owning_blob_uuid); + if (state_it == async_blob_map_.end()) { + return; + } + if (!construction_success) { + CancelBuildingBlob(owning_blob_uuid, + ConvertReferencedBlobErrorToConstructingError(reason), + context.get()); + return; + } + BlobBuildingState* state = state_it->second.get(); + DCHECK_GT(state->num_referenced_blobs_building, 0u); + if (--state->num_referenced_blobs_building == 0) { + context->CompletePendingBlob(state->data_builder); + async_blob_map_.erase(state->data_builder.uuid()); + } } -void BlobAsyncBuilderHost::DoneAndCleanup(const std::string& uuid) { - scoped_ptr<BlobBuildingState> state = std::move(async_blob_map_[uuid]); - async_blob_map_.erase(uuid); - BlobDataBuilder* builder = state->transport_strategy.blob_builder(); - builder->set_content_type(state->type); - state->done_callback.Run(*builder); +void BlobAsyncBuilderHost::FinishBuildingBlob(BlobBuildingState* state, + BlobStorageContext* context) { + if (!state->referenced_blob_uuids.empty()) { + DCHECK_EQ(0u, state->num_referenced_blobs_building); + state->num_referenced_blobs_building = 0; + // We assume re-entry is not possible, as RunOnConstructionComplete + // will schedule a task when the blob is being built. Thus we can't have the + // case where |num_referenced_blobs_building| reaches 0 in the + // ReferencedBlobFinished method before we're finished looping. + for (const std::string& referenced_uuid : state->referenced_blob_uuids) { + if (context->IsBeingBuilt(referenced_uuid)) { + state->num_referenced_blobs_building++; + context->RunOnConstructionComplete( + referenced_uuid, + base::Bind(&BlobAsyncBuilderHost::ReferencedBlobFinished, + ptr_factory_.GetWeakPtr(), state->data_builder.uuid(), + context->AsWeakPtr())); + } + } + if (state->num_referenced_blobs_building > 0) { + // We wait until referenced blobs are done. + return; + } + } + context->CompletePendingBlob(state->data_builder); + async_blob_map_.erase(state->data_builder.uuid()); } } // namespace storage diff --git a/chromium/storage/browser/blob/blob_async_builder_host.h b/chromium/storage/browser/blob/blob_async_builder_host.h index c84f2b5d348..b7e82fb3dd7 100644 --- a/chromium/storage/browser/blob/blob_async_builder_host.h +++ b/chromium/storage/browser/blob/blob_async_builder_host.h @@ -9,16 +9,20 @@ #include <stdint.h> #include <map> +#include <memory> +#include <set> #include <string> #include <vector> #include "base/callback.h" +#include "base/files/file.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/shared_memory_handle.h" -#include "storage/browser/blob/blob_async_transport_strategy.h" +#include "base/memory/weak_ptr.h" +#include "storage/browser/blob/blob_async_transport_request_builder.h" #include "storage/browser/blob/blob_data_builder.h" +#include "storage/browser/blob/blob_transport_result.h" #include "storage/browser/storage_browser_export.h" #include "storage/common/blob_storage/blob_item_bytes_request.h" #include "storage/common/blob_storage/blob_item_bytes_response.h" @@ -30,52 +34,94 @@ class SharedMemory; } namespace storage { - -// This class holds all blobs that are currently being built asynchronously for -// a child process. It sends memory request, cancel, and done messages through -// the given callbacks. -// This also includes handling 'shortcut' logic, where the host will use the -// initial data in the description instead of requesting for data if we have -// enough immediate space. +class BlobDataHandle; +class BlobStorageContext; + +// This class +// * holds all blobs that are currently being built asynchronously for a child +// process, +// * sends memory requests through the given callback in |StartBuildingBlob|, +// and uses the BlobTransportResult return value to signify other results, +// * includes all logic for deciding which async transport strategy to use, and +// * handles all blob construction communication with the BlobStorageContext. +// The method |CancelAll| must be called by the consumer, it is not called on +// destruction. class STORAGE_EXPORT BlobAsyncBuilderHost { public: + using RequestMemoryCallback = base::Callback<void( + std::unique_ptr<std::vector<storage::BlobItemBytesRequest>>, + std::unique_ptr<std::vector<base::SharedMemoryHandle>>, + std::unique_ptr<std::vector<base::File>>)>; BlobAsyncBuilderHost(); - virtual ~BlobAsyncBuilderHost(); - - // This method begins the construction of the blob given the descriptions. - // After this method is called, either of the following can happen. - // * The |done| callback is triggered immediately because we can shortcut the - // construction. - // * The |request_memory| callback is called to request memory from the - // renderer. This class waits for calls to OnMemoryResponses to continue. - // The last argument in the callback corresponds to file handle sizes. - // When all memory is recieved, the |done| callback is triggered. - // * The |cancel| callback is triggered if there is an error at any point. All - // state for the cancelled blob is cleared before |cancel| is called. - // Returns if the arguments are valid and we have a good IPC message. - bool StartBuildingBlob( + ~BlobAsyncBuilderHost(); + + // This registers the given blob internally and adds it to the storage. + // Calling this method also guarentees that the referenced blobs are kept + // alive for the duration of the construction of this blob. + // We return + // * BAD_IPC if we already have the blob registered or if we reference ourself + // in the referenced_blob_uuids. + // * CANCEL_REFERENCED_BLOB_BROKEN if one of the referenced blobs is broken or + // doesn't exist. We store the blob in the context as broken with code + // REFERENCED_BLOB_BROKEN. + // * DONE if we successfully registered the blob. + BlobTransportResult RegisterBlobUUID( + const std::string& uuid, + const std::string& content_type, + const std::string& content_disposition, + const std::set<std::string>& referenced_blob_uuids, + BlobStorageContext* context); + + // This method begins the construction of the blob given the descriptions. The + // blob uuid MUST be building in this object. + // When we return: + // * DONE: The blob is finished transfering right away, and is now + // successfully saved in the context. + // * PENDING_RESPONSES: The async builder host is waiting for responses from + // the renderer. It has called |request_memory| for these responses. + // * CANCEL_*: We have to cancel the blob construction. This function clears + // the blob's internal state and marks the blob as broken in the context + // before returning. + // * BAD_IPC: The arguments were invalid/bad. This marks the blob as broken in + // the context before returning. + BlobTransportResult StartBuildingBlob( const std::string& uuid, - const std::string& type, - const std::vector<DataElement>& descriptions, + const std::vector<DataElement>& elements, size_t memory_available, - const base::Callback< - void(const std::vector<storage::BlobItemBytesRequest>&, - const std::vector<base::SharedMemoryHandle>&, - const std::vector<uint64_t>&)>& request_memory, - const base::Callback<void(const BlobDataBuilder&)>& done, - const base::Callback<void(IPCBlobCreationCancelCode)>& cancel); + BlobStorageContext* context, + const RequestMemoryCallback& request_memory); // This is called when we have responses from the Renderer to our calls to - // the request_memory callback above. - // Returns if the arguments are valid and we have a good IPC message. - bool OnMemoryResponses(const std::string& uuid, - const std::vector<BlobItemBytesResponse>& responses); - - // This erases the blob building state. - void StopBuildingBlob(const std::string& uuid); + // the request_memory callback above. See above for return value meaning. + BlobTransportResult OnMemoryResponses( + const std::string& uuid, + const std::vector<BlobItemBytesResponse>& responses, + BlobStorageContext* context); + + // This removes the BlobBuildingState from our map and flags the blob as + // broken in the context. This can be called both from our own logic to cancel + // the blob, or from the DispatcherHost (Renderer). The blob MUST be being + // built in this builder. + // Note: if the blob isn't in the context (renderer dereferenced it before we + // finished constructing), then we don't bother touching the context. + void CancelBuildingBlob(const std::string& uuid, + IPCBlobCreationCancelCode code, + BlobStorageContext* context); + + // This clears this object of pending construction. It also handles marking + // blobs that haven't been fully constructed as broken in the context if there + // are any references being held by anyone. We know that they're being used + // by someone else if they still exist in the context. + void CancelAll(BlobStorageContext* context); + + bool IsEmpty() const { return async_blob_map_.empty(); } size_t blob_building_count() const { return async_blob_map_.size(); } + bool IsBeingBuilt(const std::string& key) const { + return async_blob_map_.find(key) != async_blob_map_.end(); + } + // For testing use only. Must be called before StartBuildingBlob. void SetMemoryConstantsForTesting(size_t max_ipc_memory_size, size_t max_shared_memory_size, @@ -87,36 +133,62 @@ class STORAGE_EXPORT BlobAsyncBuilderHost { private: struct BlobBuildingState { - BlobBuildingState(); + // |refernced_blob_handles| should be all handles generated from the set + // of |refernced_blob_uuids|. + BlobBuildingState( + const std::string& uuid, + std::set<std::string> referenced_blob_uuids, + std::vector<std::unique_ptr<BlobDataHandle>>* referenced_blob_handles); ~BlobBuildingState(); - std::string type; - BlobAsyncTransportStrategy transport_strategy; - size_t next_request; - size_t num_fulfilled_requests; - scoped_ptr<base::SharedMemory> shared_memory_block; + BlobAsyncTransportRequestBuilder request_builder; + BlobDataBuilder data_builder; + std::vector<bool> request_received; + size_t next_request = 0; + size_t num_fulfilled_requests = 0; + std::unique_ptr<base::SharedMemory> shared_memory_block; // This is the number of requests that have been sent to populate the above // shared data. We won't ask for more data in shared memory until all // requests have been responded to. - size_t num_shared_memory_requests; + size_t num_shared_memory_requests = 0; // Only relevant if num_shared_memory_requests is > 0 - size_t current_shared_memory_handle_index; - - base::Callback<void(const std::vector<storage::BlobItemBytesRequest>&, - const std::vector<base::SharedMemoryHandle>&, - const std::vector<uint64_t>&)> request_memory_callback; - base::Callback<void(const BlobDataBuilder&)> done_callback; - base::Callback<void(IPCBlobCreationCancelCode)> cancel_callback; + size_t current_shared_memory_handle_index = 0; + + // We save these to double check that the RegisterBlob and StartBuildingBlob + // messages are in sync. + std::set<std::string> referenced_blob_uuids; + // These are the blobs that are referenced in the newly constructed blob. + // We use these to make sure they stay alive while we create the new blob, + // and to wait until any blobs that are not done building are fully + // constructed. + std::vector<std::unique_ptr<BlobDataHandle>> referenced_blob_handles; + + // These are the number of blobs we're waiting for before we can start + // building. + size_t num_referenced_blobs_building = 0; + + BlobAsyncBuilderHost::RequestMemoryCallback request_memory_callback; }; - typedef std::map<std::string, scoped_ptr<BlobBuildingState>> AsyncBlobMap; + typedef std::map<std::string, std::unique_ptr<BlobBuildingState>> + AsyncBlobMap; // This is the 'main loop' of our memory requests to the renderer. - void ContinueBlobMemoryRequests(const std::string& uuid); - - void CancelAndCleanup(const std::string& uuid, - IPCBlobCreationCancelCode code); - void DoneAndCleanup(const std::string& uuid); + BlobTransportResult ContinueBlobMemoryRequests(const std::string& uuid, + BlobStorageContext* context); + + // This is our callback for when we want to finish the blob and we're waiting + // for blobs we reference to be built. When the last callback occurs, we + // complete the blob and erase our internal state. + void ReferencedBlobFinished(const std::string& uuid, + base::WeakPtr<BlobStorageContext> context, + bool construction_success, + IPCBlobCreationCancelCode reason); + + // This finishes creating the blob in the context, decrements blob references + // that we were holding during construction, and erases our state. + void FinishBuildingBlob(BlobBuildingState* state, + BlobStorageContext* context); AsyncBlobMap async_blob_map_; @@ -125,6 +197,8 @@ class STORAGE_EXPORT BlobAsyncBuilderHost { size_t max_shared_memory_size_ = kBlobStorageMaxSharedMemoryBytes; uint64_t max_file_size_ = kBlobStorageMaxFileSizeBytes; + base::WeakPtrFactory<BlobAsyncBuilderHost> ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(BlobAsyncBuilderHost); }; diff --git a/chromium/storage/browser/blob/blob_async_transport_strategy.cc b/chromium/storage/browser/blob/blob_async_transport_request_builder.cc index edae52c79ed..a77d408ca8f 100644 --- a/chromium/storage/browser/blob/blob_async_transport_strategy.cc +++ b/chromium/storage/browser/blob/blob_async_transport_request_builder.cc @@ -8,7 +8,7 @@ #include <algorithm> #include "base/numerics/safe_math.h" -#include "storage/browser/blob/blob_async_transport_strategy.h" +#include "storage/browser/blob/blob_async_transport_request_builder.h" #include "storage/common/blob_storage/blob_storage_constants.h" namespace storage { @@ -37,7 +37,7 @@ bool IsBytes(DataElement::Type type) { class FileStorageStrategy { public: FileStorageStrategy( - std::vector<BlobAsyncTransportStrategy::RendererMemoryItemRequest>* + std::vector<BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest>* requests, BlobDataBuilder* builder) : requests(requests), builder(builder), current_item_index(0) {} @@ -49,7 +49,7 @@ class FileStorageStrategy { size_t segment_index, uint64_t segment_offset, uint64_t size) { - BlobAsyncTransportStrategy::RendererMemoryItemRequest request; + BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest request; request.browser_item_index = current_item_index; request.browser_item_offset = 0; request.message.request_number = requests->size(); @@ -72,7 +72,8 @@ class FileStorageStrategy { void Done() {} - std::vector<BlobAsyncTransportStrategy::RendererMemoryItemRequest>* requests; + std::vector<BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest>* + requests; BlobDataBuilder* builder; size_t current_item_index; @@ -84,7 +85,7 @@ class SharedMemoryStorageStrategy { public: SharedMemoryStorageStrategy( size_t max_segment_size, - std::vector<BlobAsyncTransportStrategy::RendererMemoryItemRequest>* + std::vector<BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest>* requests, BlobDataBuilder* builder) : requests(requests), @@ -104,7 +105,7 @@ class SharedMemoryStorageStrategy { current_item_index++; current_item_size = 0; } - BlobAsyncTransportStrategy::RendererMemoryItemRequest request; + BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest request; request.browser_item_index = current_item_index; request.browser_item_offset = current_item_size; request.message.request_number = requests->size(); @@ -136,7 +137,8 @@ class SharedMemoryStorageStrategy { } } - std::vector<BlobAsyncTransportStrategy::RendererMemoryItemRequest>* requests; + std::vector<BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest>* + requests; size_t max_segment_size; BlobDataBuilder* builder; @@ -191,101 +193,61 @@ void ForEachWithSegment(const std::vector<DataElement>& elements, } } // namespace -BlobAsyncTransportStrategy::RendererMemoryItemRequest:: +BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest:: RendererMemoryItemRequest() - : browser_item_index(0), browser_item_offset(0), received(false) {} + : browser_item_index(0), browser_item_offset(0) {} -BlobAsyncTransportStrategy::BlobAsyncTransportStrategy() - : error_(BlobAsyncTransportStrategy::ERROR_NONE), total_bytes_size_(0) {} +BlobAsyncTransportRequestBuilder::BlobAsyncTransportRequestBuilder() + : total_bytes_size_(0) {} -BlobAsyncTransportStrategy::~BlobAsyncTransportStrategy() {} +BlobAsyncTransportRequestBuilder::~BlobAsyncTransportRequestBuilder() {} -// if total_blob_size > |memory_available| (say 400MB) -// Request all data in files -// (Segment all of the existing data into -// file blocks, of <= |max_file_size|) -// else if total_blob_size > |max_ipc_memory_size| (say 150KB) -// Request all data in shared memory -// (Segment all of the existing data into -// shared memory blocks, of <= |max_shared_memory_size|) -// else -// Request all data to be sent over IPC -void BlobAsyncTransportStrategy::Initialize( - size_t max_ipc_memory_size, - size_t max_shared_memory_size, +// Initializes the transport strategy for file requests. +void BlobAsyncTransportRequestBuilder::InitializeForFileRequests( size_t max_file_size, - uint64_t disk_space_left, - size_t memory_available, - const std::string& uuid, - const std::vector<DataElement>& blob_item_infos) { - DCHECK(handle_sizes_.empty()); + uint64_t blob_total_size, + const std::vector<DataElement>& elements, + BlobDataBuilder* builder) { DCHECK(requests_.empty()); - DCHECK(!builder_.get()); - builder_.reset(new BlobDataBuilder(uuid)); - error_ = BlobAsyncTransportStrategy::ERROR_NONE; - - size_t memory_items = 0; - base::CheckedNumeric<uint64_t> total_size_checked = 0; - for (const auto& info : blob_item_infos) { - if (!IsBytes(info.type())) { - continue; - } - total_size_checked += info.length(); - ++memory_items; - } - - if (!total_size_checked.IsValid()) { - DVLOG(1) << "Impossible total size of all memory elements."; - error_ = BlobAsyncTransportStrategy::ERROR_INVALID_PARAMS; - return; - } - - total_bytes_size_ = total_size_checked.ValueOrDie(); - - // See if we have enough memory. - if (total_bytes_size_ > - disk_space_left + static_cast<uint64_t>(memory_available)) { - error_ = BlobAsyncTransportStrategy::ERROR_TOO_LARGE; - return; - } - - // If we're more than the available memory, then we're going straight to disk. - if (total_bytes_size_ > memory_available) { - if (total_bytes_size_ > disk_space_left) { - error_ = BlobAsyncTransportStrategy::ERROR_TOO_LARGE; - return; - } - ComputeHandleSizes(total_bytes_size_, max_file_size, &handle_sizes_); - FileStorageStrategy strategy(&requests_, builder_.get()); - ForEachWithSegment(blob_item_infos, static_cast<uint64_t>(max_file_size), - &strategy); - return; - } + total_bytes_size_ = blob_total_size; + ComputeHandleSizes(total_bytes_size_, max_file_size, &file_sizes_); + FileStorageStrategy strategy(&requests_, builder); + ForEachWithSegment(elements, static_cast<uint64_t>(max_file_size), &strategy); +} - if (total_bytes_size_ > max_ipc_memory_size) { - // Note: The size must be <= std::numeric_limits<size_t>::max(). Otherwise - // we are guarenteed to be caught by the if statement above, - // |total_bytes_size_ > memory_available|. - ComputeHandleSizes(total_bytes_size_, max_shared_memory_size, - &handle_sizes_); - SharedMemoryStorageStrategy strategy(max_shared_memory_size, &requests_, - builder_.get()); - ForEachWithSegment(blob_item_infos, - static_cast<uint64_t>(max_shared_memory_size), - &strategy); - return; - } +void BlobAsyncTransportRequestBuilder::InitializeForSharedMemoryRequests( + size_t max_shared_memory_size, + uint64_t blob_total_size, + const std::vector<DataElement>& elements, + BlobDataBuilder* builder) { + DCHECK(requests_.empty()); + DCHECK(blob_total_size <= std::numeric_limits<size_t>::max()); + total_bytes_size_ = blob_total_size; + ComputeHandleSizes(total_bytes_size_, max_shared_memory_size, + &shared_memory_sizes_); + SharedMemoryStorageStrategy strategy(max_shared_memory_size, &requests_, + builder); + ForEachWithSegment(elements, static_cast<uint64_t>(max_shared_memory_size), + &strategy); +} - // Since they can all fit in IPC memory, we don't need to segment anything, - // and just request them straight in IPC. - size_t items_length = blob_item_infos.size(); +void BlobAsyncTransportRequestBuilder::InitializeForIPCRequests( + size_t max_ipc_memory_size, + uint64_t blob_total_size, + const std::vector<DataElement>& elements, + BlobDataBuilder* builder) { + DCHECK(requests_.empty()); + // We don't segment anything, and just request the memory items directly + // in IPC. + size_t items_length = elements.size(); + total_bytes_size_ = blob_total_size; for (size_t i = 0; i < items_length; i++) { - const auto& info = blob_item_infos.at(i); + const auto& info = elements.at(i); if (!IsBytes(info.type())) { - builder_->AppendIPCDataElement(info); + builder->AppendIPCDataElement(info); continue; } - BlobAsyncTransportStrategy::RendererMemoryItemRequest request; + BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest request; request.browser_item_index = i; request.browser_item_offset = 0; request.message.request_number = requests_.size(); @@ -294,12 +256,12 @@ void BlobAsyncTransportStrategy::Initialize( request.message.renderer_item_offset = 0; request.message.size = info.length(); requests_.push_back(request); - builder_->AppendFutureData(info.length()); + builder->AppendFutureData(info.length()); } } /* static */ -bool BlobAsyncTransportStrategy::ShouldBeShortcut( +bool BlobAsyncTransportRequestBuilder::ShouldBeShortcut( const std::vector<DataElement>& elements, size_t memory_available) { base::CheckedNumeric<size_t> shortcut_bytes = 0; @@ -319,7 +281,7 @@ bool BlobAsyncTransportStrategy::ShouldBeShortcut( } /* static */ -void BlobAsyncTransportStrategy::ComputeHandleSizes( +void BlobAsyncTransportRequestBuilder::ComputeHandleSizes( uint64_t total_memory_size, size_t max_segment_size, std::vector<size_t>* segment_sizes) { diff --git a/chromium/storage/browser/blob/blob_async_transport_request_builder.h b/chromium/storage/browser/blob/blob_async_transport_request_builder.h new file mode 100644 index 00000000000..10dde5ff6ff --- /dev/null +++ b/chromium/storage/browser/blob/blob_async_transport_request_builder.h @@ -0,0 +1,138 @@ +// Copyright 2015 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. + +#ifndef STORAGE_BROWSER_BLOB_BLOB_ASYNC_TRANSPORT_REQUEST_BUILDER_H_ +#define STORAGE_BROWSER_BLOB_BLOB_ASYNC_TRANSPORT_REQUEST_BUILDER_H_ + +#include <stddef.h> +#include <stdint.h> + +#include <map> +#include <memory> +#include <vector> + +#include "base/macros.h" +#include "storage/browser/blob/blob_data_builder.h" +#include "storage/browser/storage_browser_export.h" +#include "storage/common/blob_storage/blob_item_bytes_request.h" +#include "storage/common/data_element.h" + +namespace storage { + +// This class generates the requests needed to asynchronously transport the +// given blob items from the renderer to the browser. The main job of this class +// is to segment the memory being transfered to efficiently use shared memory, +// file, and IPC max sizes. +// Note: This class does not compute requests by using the 'shortcut' method, +// where the data is already present in the blob description, and will +// always give the caller requests for requesting all data from the +// renderer. +class STORAGE_EXPORT BlobAsyncTransportRequestBuilder { + public: + struct RendererMemoryItemRequest { + RendererMemoryItemRequest(); + // This is the index of the item in the builder on the browser side. + size_t browser_item_index; + // Note: For files this offset should always be 0, as the file offset in + // segmentation is handled by the handle_offset in the message. This + // offset is used for populating a chunk when the data comes back to + // the browser. + size_t browser_item_offset; + BlobItemBytesRequest message; + }; + + BlobAsyncTransportRequestBuilder(); + virtual ~BlobAsyncTransportRequestBuilder(); + + // Initializes the request builder for file requests. One or more files are + // created to hold the given data. Each file can hold data from multiple + // items, and the data from each item can be in multiple files. + // See file_handle_sizes() for the generated file sizes. + // max_file_size: This is the maximum size for a file to back a blob. + // blob_total_size: This is the total in-memory size of the blob. + // elements: These are the descriptions of the blob items being sent from the + // renderer. + // builder: This is the builder that is populated with the 'future' versions + // of the data elements. In this case, we call 'AppendFutureData' in + // the items that we expect to be backed by files writen by the + // renderer. + void InitializeForFileRequests(size_t max_file_size, + uint64_t blob_total_size, + const std::vector<DataElement>& elements, + BlobDataBuilder* builder); + + // Initializes the request builder for shared memory requests. We try to + // consolidate as much memory as possible in each shared memory segment we + // use. + // See shared_memory_handle_sizes() for the shared memory sizes. + // max_shared_memory_size: This is the maximum size for a shared memory + // segment used to transport the data between renderer + // and browser. + // blob_total_size: This is the total in-memory size of the blob. + // elements: These are the descriptions of the blob items being sent from the + // renderer. + // builder: This is the builder that is populated with the 'future' versions + // of the data elements. In this case, we call 'AppendFutureData' for + // the items we expect to be populated later. + void InitializeForSharedMemoryRequests( + size_t max_shared_memory_size, + uint64_t blob_total_size, + const std::vector<DataElement>& elements, + BlobDataBuilder* builder); + + // Initializes the request builder for IPC requests. We put as much memory + // in a single IPC request as possible. + // max_ipc_memory_size: This is the maximum size for an IPC message which will + // be used to transport memory from the renderer to the + // browser. + // blob_total_size: This is the total in-memory size of the blob. + // elements: These are the descriptions of the blob items being sent from the + // renderer. + // builder: This is the builder that is populated with the 'future' versions + // of the data elements. In this case, we call 'AppendFutureData' for + // the items we expect to be populated later. + void InitializeForIPCRequests(size_t max_ipc_memory_size, + uint64_t blob_total_size, + const std::vector<DataElement>& elements, + BlobDataBuilder* builder); + + // The sizes of the shared memory handles being used (by handle index). + const std::vector<size_t>& shared_memory_sizes() const { + return shared_memory_sizes_; + } + + // The sizes of the file handles being used (by handle index). + const std::vector<size_t>& file_sizes() const { return file_sizes_; } + + // The requests for memory, segmented as described above, along with their + // destination browser indexes and offsets. + const std::vector<RendererMemoryItemRequest>& requests() const { + return requests_; + } + + // The total bytes size of memory items in the blob. + uint64_t total_bytes_size() const { return total_bytes_size_; } + + static bool ShouldBeShortcut(const std::vector<DataElement>& items, + size_t memory_available); + + private: + static void ComputeHandleSizes(uint64_t total_memory_size, + size_t max_segment_size, + std::vector<size_t>* segment_sizes); + + std::vector<size_t> shared_memory_sizes_; + // The size of the files is capped by the |max_file_size| argument in + // InitializeForFileRequests, so we can just use size_t. + std::vector<size_t> file_sizes_; + + uint64_t total_bytes_size_; + std::vector<RendererMemoryItemRequest> requests_; + + DISALLOW_COPY_AND_ASSIGN(BlobAsyncTransportRequestBuilder); +}; + +} // namespace storage + +#endif // STORAGE_BROWSER_BLOB_BLOB_ASYNC_TRANSPORT_REQUEST_BUILDER_H_ diff --git a/chromium/storage/browser/blob/blob_async_transport_strategy.h b/chromium/storage/browser/blob/blob_async_transport_strategy.h deleted file mode 100644 index 3e0777182cb..00000000000 --- a/chromium/storage/browser/blob/blob_async_transport_strategy.h +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2015 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. - -#ifndef STORAGE_BROWSER_BLOB_BLOB_ASYNC_TRANSPORT_STRATEGY_H_ -#define STORAGE_BROWSER_BLOB_BLOB_ASYNC_TRANSPORT_STRATEGY_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <map> -#include <vector> - -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "storage/browser/blob/blob_data_builder.h" -#include "storage/browser/storage_browser_export.h" -#include "storage/common/blob_storage/blob_item_bytes_request.h" -#include "storage/common/data_element.h" - -namespace storage { - -// This class computes and stores the strategy for asynchronously transporting -// memory from the renderer to the browser. We take memory constraints of our -// system and the description of a blob, and figure out: -// 1) How to store the blob data in the browser process: in memory or on disk. -// 2) How to transport the data from the renderer: ipc payload, shared memory, -// or file handles. -// We then generate data requests for that blob's memory and seed a -// BlobDataBuilder for storing that data. -// -// Note: This class does not compute requests by using the 'shortcut' method, -// where the data is already present in the blob description, and will -// always give the caller the full strategy for requesting all data from -// the renderer. -class STORAGE_EXPORT BlobAsyncTransportStrategy { - public: - enum Error { - ERROR_NONE = 0, - ERROR_TOO_LARGE, // This item can't fit in disk or memory - ERROR_INVALID_PARAMS - }; - - struct RendererMemoryItemRequest { - RendererMemoryItemRequest(); - // This is the index of the item in the builder on the browser side. - size_t browser_item_index; - // Note: For files this offset should always be 0, as the file offset in - // segmentation is handled by the handle_offset in the message. This - // offset is used for populating a chunk when the data comes back to - // the browser. - size_t browser_item_offset; - BlobItemBytesRequest message; - bool received; - }; - - BlobAsyncTransportStrategy(); - virtual ~BlobAsyncTransportStrategy(); - - // This call does the computation to create the requests and builder for the - // blob given the memory constraints and blob description. |memory_available| - // is the total amount of memory we can offer for storing blobs. - // This method can only be called once. - void Initialize(size_t max_ipc_memory_size, - size_t max_shared_memory_size, - size_t max_file_size, - uint64_t disk_space_left, - size_t memory_available, - const std::string& uuid, - const std::vector<DataElement>& blob_item_infos); - - // The sizes of the handles being used (by handle index) in the async - // operation. This is used for both files or shared memory, as their use is - // mutually exclusive. - const std::vector<size_t>& handle_sizes() const { return handle_sizes_; } - - // The requests for memory, segmented as described above, along with their - // destination browser indexes and offsets. - const std::vector<RendererMemoryItemRequest>& requests() const { - return requests_; - } - - // Marks the request at the given request number as recieved. - void MarkRequestAsReceived(size_t request_num) { - DCHECK_LT(request_num, requests_.size()); - requests_[request_num].received = true; - } - - // A BlobDataBuilder which can be used to construct the Blob in the - // BlobStorageContext object after: - // * The bytes items from AppendFutureData are populated by - // PopulateFutureData. - // * The temporary files from AppendFutureFile are populated by - // PopulateFutureFile. - BlobDataBuilder* blob_builder() { return builder_.get(); } - - // The total bytes size of memory items in the blob. - uint64_t total_bytes_size() const { return total_bytes_size_; } - - Error error() const { return error_; } - - static bool ShouldBeShortcut(const std::vector<DataElement>& items, - size_t memory_available); - - private: - static void ComputeHandleSizes(uint64_t total_memory_size, - size_t max_segment_size, - std::vector<size_t>* segment_sizes); - - Error error_; - - // We use the same vector for shared memory handle sizes and file handle sizes - // because we only use one for any strategy. The size of the handles is capped - // by the |max_file_size| argument in Initialize, so we can just use size_t. - std::vector<size_t> handle_sizes_; - - uint64_t total_bytes_size_; - std::vector<RendererMemoryItemRequest> requests_; - scoped_ptr<BlobDataBuilder> builder_; - - DISALLOW_COPY_AND_ASSIGN(BlobAsyncTransportStrategy); -}; - -} // namespace storage - -#endif // STORAGE_BROWSER_BLOB_BLOB_ASYNC_TRANSPORT_STRATEGY_H_ diff --git a/chromium/storage/browser/blob/blob_data_builder.cc b/chromium/storage/browser/blob/blob_data_builder.cc index b6999104b95..6b6210653f8 100644 --- a/chromium/storage/browser/blob/blob_data_builder.cc +++ b/chromium/storage/browser/blob/blob_data_builder.cc @@ -6,6 +6,8 @@ #include <stddef.h> #include <stdint.h> + +#include <memory> #include <utility> #include "base/numerics/safe_conversions.h" @@ -56,14 +58,14 @@ void BlobDataBuilder::AppendIPCDataElement(const DataElement& ipc_data) { void BlobDataBuilder::AppendData(const char* data, size_t length) { if (!length) return; - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToBytes(data, length); items_.push_back(new BlobDataItem(std::move(element))); } size_t BlobDataBuilder::AppendFutureData(size_t length) { CHECK_NE(length, 0u); - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToBytesDescription(length); items_.push_back(new BlobDataItem(std::move(element))); return items_.size() - 1; @@ -104,7 +106,7 @@ bool BlobDataBuilder::PopulateFutureData(size_t index, size_t BlobDataBuilder::AppendFutureFile(uint64_t offset, uint64_t length) { CHECK_NE(length, 0ull); - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToFilePathRange(base::FilePath::FromUTF8Unsafe(std::string( kAppendFutureFileTemporaryFileName)), offset, length, base::Time()); @@ -129,7 +131,7 @@ bool BlobDataBuilder::PopulateFutureFile( } uint64_t length = old_element->length(); uint64_t offset = old_element->offset(); - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToFilePathRange(file_reference->path(), offset, length, expected_modification_time); items_[index] = new BlobDataItem(std::move(element), file_reference); @@ -140,7 +142,7 @@ void BlobDataBuilder::AppendFile(const base::FilePath& file_path, uint64_t offset, uint64_t length, const base::Time& expected_modification_time) { - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToFilePathRange(file_path, offset, length, expected_modification_time); items_.push_back(new BlobDataItem(std::move(element), @@ -151,13 +153,13 @@ void BlobDataBuilder::AppendBlob(const std::string& uuid, uint64_t offset, uint64_t length) { DCHECK_GT(length, 0ul); - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToBlobRange(uuid, offset, length); items_.push_back(new BlobDataItem(std::move(element))); } void BlobDataBuilder::AppendBlob(const std::string& uuid) { - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToBlob(uuid); items_.push_back(new BlobDataItem(std::move(element))); } @@ -168,7 +170,7 @@ void BlobDataBuilder::AppendFileSystemFile( uint64_t length, const base::Time& expected_modification_time) { DCHECK_GT(length, 0ul); - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToFileSystemUrlRange(url, offset, length, expected_modification_time); items_.push_back(new BlobDataItem(std::move(element))); @@ -178,7 +180,7 @@ void BlobDataBuilder::AppendDiskCacheEntry( const scoped_refptr<DataHandle>& data_handle, disk_cache::Entry* disk_cache_entry, int disk_cache_stream_index) { - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToDiskCacheEntryRange( 0U, disk_cache_entry->GetDataSize(disk_cache_stream_index)); items_.push_back(new BlobDataItem(std::move(element), data_handle, diff --git a/chromium/storage/browser/blob/blob_data_builder.h b/chromium/storage/browser/blob/blob_data_builder.h index 09601880178..5600ca8eab8 100644 --- a/chromium/storage/browser/blob/blob_data_builder.h +++ b/chromium/storage/browser/blob/blob_data_builder.h @@ -165,6 +165,10 @@ inline bool operator==(const BlobDataSnapshot& a, const BlobDataBuilder& b) { return true; } +inline bool operator==(const BlobDataBuilder& a, const BlobDataSnapshot& b) { + return b == a; +} + inline bool operator!=(const BlobDataSnapshot& a, const BlobDataBuilder& b) { return !(a == b); } @@ -173,6 +177,10 @@ inline bool operator!=(const BlobDataBuilder& a, const BlobDataBuilder& b) { return !(a == b); } +inline bool operator!=(const BlobDataBuilder& a, const BlobDataSnapshot& b) { + return b != a; +} + #endif // defined(UNIT_TEST) } // namespace storage diff --git a/chromium/storage/browser/blob/blob_data_handle.cc b/chromium/storage/browser/blob/blob_data_handle.cc index efe13b16ea5..55e63a1b620 100644 --- a/chromium/storage/browser/blob/blob_data_handle.cc +++ b/chromium/storage/browser/blob/blob_data_handle.cc @@ -6,10 +6,14 @@ #include <stdint.h> +#include <memory> + #include "base/bind.h" +#include "base/callback.h" #include "base/location.h" #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" #include "base/task_runner.h" #include "base/time/time.h" @@ -22,26 +26,27 @@ #include "url/gurl.h" namespace storage { +using BlobState = BlobStorageRegistry::BlobState; namespace { class FileStreamReaderProviderImpl : public BlobReader::FileStreamReaderProvider { public: - FileStreamReaderProviderImpl(FileSystemContext* file_system_context) + explicit FileStreamReaderProviderImpl(FileSystemContext* file_system_context) : file_system_context_(file_system_context) {} ~FileStreamReaderProviderImpl() override {} - scoped_ptr<FileStreamReader> CreateForLocalFile( + std::unique_ptr<FileStreamReader> CreateForLocalFile( base::TaskRunner* task_runner, const base::FilePath& file_path, int64_t initial_offset, const base::Time& expected_modification_time) override { - return make_scoped_ptr(FileStreamReader::CreateForLocalFile( + return base::WrapUnique(FileStreamReader::CreateForLocalFile( task_runner, file_path, initial_offset, expected_modification_time)); } - scoped_ptr<FileStreamReader> CreateFileStreamReader( + std::unique_ptr<FileStreamReader> CreateFileStreamReader( const GURL& filesystem_url, int64_t offset, int64_t max_bytes_to_read, @@ -70,20 +75,15 @@ BlobDataHandle::BlobDataHandleShared::BlobDataHandleShared( context_->IncrementBlobRefCount(uuid); } -scoped_ptr<BlobReader> BlobDataHandle::CreateReader( +std::unique_ptr<BlobReader> BlobDataHandle::CreateReader( FileSystemContext* file_system_context, base::SequencedTaskRunner* file_task_runner) const { - return scoped_ptr<BlobReader>(new BlobReader( - this, scoped_ptr<BlobReader::FileStreamReaderProvider>( + return std::unique_ptr<BlobReader>(new BlobReader( + this, std::unique_ptr<BlobReader::FileStreamReaderProvider>( new FileStreamReaderProviderImpl(file_system_context)), file_task_runner)); } -scoped_ptr<BlobDataSnapshot> -BlobDataHandle::BlobDataHandleShared::CreateSnapshot() const { - return context_->CreateSnapshot(uuid_); -} - BlobDataHandle::BlobDataHandleShared::~BlobDataHandleShared() { if (context_.get()) context_->DecrementBlobRefCount(uuid_); @@ -109,15 +109,43 @@ BlobDataHandle::BlobDataHandle(const BlobDataHandle& other) { } BlobDataHandle::~BlobDataHandle() { - BlobDataHandleShared* raw = shared_.get(); - raw->AddRef(); - shared_ = nullptr; - io_task_runner_->ReleaseSoon(FROM_HERE, raw); + if (!io_task_runner_->RunsTasksOnCurrentThread()) { + BlobDataHandleShared* raw = shared_.get(); + raw->AddRef(); + shared_ = nullptr; + io_task_runner_->ReleaseSoon(FROM_HERE, raw); + } +} + +bool BlobDataHandle::IsBeingBuilt() const { + DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); + if (!shared_->context_) + return false; + return shared_->context_->IsBeingBuilt(shared_->uuid_); +} + +bool BlobDataHandle::IsBroken() const { + DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); + if (!shared_->context_) + return true; + return shared_->context_->IsBroken(shared_->uuid_); +} + +void BlobDataHandle::RunOnConstructionComplete( + const BlobConstructedCallback& done) { + DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); + if (!shared_->context_.get()) { + done.Run(false, IPCBlobCreationCancelCode::UNKNOWN); + return; + } + shared_->context_->RunOnConstructionComplete(shared_->uuid_, done); } -scoped_ptr<BlobDataSnapshot> BlobDataHandle::CreateSnapshot() const { +std::unique_ptr<BlobDataSnapshot> BlobDataHandle::CreateSnapshot() const { DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); - return shared_->CreateSnapshot(); + if (!shared_->context_.get()) + return nullptr; + return shared_->context_->CreateSnapshot(shared_->uuid_); } const std::string& BlobDataHandle::uuid() const { diff --git a/chromium/storage/browser/blob/blob_data_handle.h b/chromium/storage/browser/blob/blob_data_handle.h index 7d0bef83ee8..3f4529346b1 100644 --- a/chromium/storage/browser/blob/blob_data_handle.h +++ b/chromium/storage/browser/blob/blob_data_handle.h @@ -5,14 +5,16 @@ #ifndef STORAGE_BROWSER_BLOB_BLOB_DATA_HANDLE_H_ #define STORAGE_BROWSER_BLOB_BLOB_DATA_HANDLE_H_ +#include <memory> #include <string> +#include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/supports_user_data.h" #include "storage/browser/storage_browser_export.h" +#include "storage/common/blob_storage/blob_storage_constants.h" namespace base { class SequencedTaskRunner; @@ -37,13 +39,35 @@ class FileSystemContext; class STORAGE_EXPORT BlobDataHandle : public base::SupportsUserData::Data { public: + // True means the blob was constructed successfully, and false means that + // there was an error, which is reported in the second argument. + using BlobConstructedCallback = + base::Callback<void(bool, IPCBlobCreationCancelCode)>; + BlobDataHandle(const BlobDataHandle& other); // May be copied on any thread. ~BlobDataHandle() override; // May be deleted on any thread. + // Returns if this blob is still constructing. If so, one can use the + // RunOnConstructionComplete to wait. + // Must be called on IO thread. + bool IsBeingBuilt() const; + + // Returns if this blob is broken, and there is no data associated with it. + // Must be called on IO thread. + bool IsBroken() const; + + // The callback will be run on the IO thread when construction of the blob + // is complete. If construction is already complete, then the task is run + // immediately on the current message loop (i.e. IO thread). + // Must be called on IO thread. Returns if construction successful. + // Calling this multiple times results in registering multiple + // completion callbacks. + void RunOnConstructionComplete(const BlobConstructedCallback& done); + // A BlobReader is used to read the data from the blob. This object is // intended to be transient and should not be stored for any extended period // of time. - scoped_ptr<BlobReader> CreateReader( + std::unique_ptr<BlobReader> CreateReader( FileSystemContext* file_system_context, base::SequencedTaskRunner* file_task_runner) const; @@ -55,9 +79,11 @@ class STORAGE_EXPORT BlobDataHandle const std::string& content_disposition() const; // This call and the destruction of the returned snapshot must be called - // on the IO thread. + // on the IO thread. If the blob is broken, then we return a nullptr here. + // Please do not call this, and use CreateReader instead. It appropriately + // waits until the blob is built before having a size (see CalculateSize). // TODO(dmurph): Make this protected, where only the BlobReader can call it. - scoped_ptr<BlobDataSnapshot> CreateSnapshot() const; + std::unique_ptr<BlobDataSnapshot> CreateSnapshot() const; private: // Internal class whose destructor is guarenteed to be called on the IO @@ -70,8 +96,6 @@ class STORAGE_EXPORT BlobDataHandle const std::string& content_disposition, BlobStorageContext* context); - scoped_ptr<BlobDataSnapshot> CreateSnapshot() const; - private: friend class base::DeleteHelper<BlobDataHandleShared>; friend class base::RefCountedThreadSafe<BlobDataHandleShared>; diff --git a/chromium/storage/browser/blob/blob_data_item.cc b/chromium/storage/browser/blob/blob_data_item.cc index 70495ed7c56..0e44427eb57 100644 --- a/chromium/storage/browser/blob/blob_data_item.cc +++ b/chromium/storage/browser/blob/blob_data_item.cc @@ -4,6 +4,7 @@ #include "storage/browser/blob/blob_data_item.h" +#include <memory> #include <utility> namespace storage { @@ -11,19 +12,19 @@ namespace storage { BlobDataItem::DataHandle::~DataHandle() { } -BlobDataItem::BlobDataItem(scoped_ptr<DataElement> item) +BlobDataItem::BlobDataItem(std::unique_ptr<DataElement> item) : item_(std::move(item)), disk_cache_entry_(nullptr), disk_cache_stream_index_(-1) {} -BlobDataItem::BlobDataItem(scoped_ptr<DataElement> item, +BlobDataItem::BlobDataItem(std::unique_ptr<DataElement> item, const scoped_refptr<DataHandle>& data_handle) : item_(std::move(item)), data_handle_(data_handle), disk_cache_entry_(nullptr), disk_cache_stream_index_(-1) {} -BlobDataItem::BlobDataItem(scoped_ptr<DataElement> item, +BlobDataItem::BlobDataItem(std::unique_ptr<DataElement> item, const scoped_refptr<DataHandle>& data_handle, disk_cache::Entry* entry, int disk_cache_stream_index) diff --git a/chromium/storage/browser/blob/blob_data_item.h b/chromium/storage/browser/blob/blob_data_item.h index c0495c31078..6212b7c541d 100644 --- a/chromium/storage/browser/blob/blob_data_item.h +++ b/chromium/storage/browser/blob/blob_data_item.h @@ -7,6 +7,7 @@ #include <stdint.h> +#include <memory> #include <ostream> #include <string> @@ -65,16 +66,16 @@ class STORAGE_EXPORT BlobDataItem : public base::RefCounted<BlobDataItem> { friend class base::RefCounted<BlobDataItem>; friend STORAGE_EXPORT void PrintTo(const BlobDataItem& x, ::std::ostream* os); - explicit BlobDataItem(scoped_ptr<DataElement> item); - BlobDataItem(scoped_ptr<DataElement> item, + explicit BlobDataItem(std::unique_ptr<DataElement> item); + BlobDataItem(std::unique_ptr<DataElement> item, const scoped_refptr<DataHandle>& data_handle); - BlobDataItem(scoped_ptr<DataElement> item, + BlobDataItem(std::unique_ptr<DataElement> item, const scoped_refptr<DataHandle>& data_handle, disk_cache::Entry* entry, int disk_cache_stream_index_); virtual ~BlobDataItem(); - scoped_ptr<DataElement> item_; + std::unique_ptr<DataElement> item_; scoped_refptr<DataHandle> data_handle_; // This naked pointer is safe because the scope is protected by the DataHandle diff --git a/chromium/storage/browser/blob/blob_data_snapshot.cc b/chromium/storage/browser/blob/blob_data_snapshot.cc index 0071a11dfd2..45a85242e08 100644 --- a/chromium/storage/browser/blob/blob_data_snapshot.cc +++ b/chromium/storage/browser/blob/blob_data_snapshot.cc @@ -47,4 +47,16 @@ size_t BlobDataSnapshot::GetMemoryUsage() const { return memory; } +void PrintTo(const BlobDataSnapshot& x, std::ostream* os) { + DCHECK(os); + *os << "<BlobDataSnapshot>{uuid: " << x.uuid() + << ", content_type: " << x.content_type_ + << ", content_disposition: " << x.content_disposition_ << ", items: ["; + for (const auto& item : x.items_) { + PrintTo(*item, os); + *os << ", "; + } + *os << "]}"; +} + } // namespace storage diff --git a/chromium/storage/browser/blob/blob_data_snapshot.h b/chromium/storage/browser/blob/blob_data_snapshot.h index 31b2973d4c1..481629acea8 100644 --- a/chromium/storage/browser/blob/blob_data_snapshot.h +++ b/chromium/storage/browser/blob/blob_data_snapshot.h @@ -44,6 +44,8 @@ class STORAGE_EXPORT BlobDataSnapshot : public base::SupportsUserData::Data { private: friend class BlobDataBuilder; friend class BlobStorageContext; + friend STORAGE_EXPORT void PrintTo(const BlobDataSnapshot& x, + ::std::ostream* os); BlobDataSnapshot(const std::string& uuid, const std::string& content_type, const std::string& content_disposition); diff --git a/chromium/storage/browser/blob/blob_reader.cc b/chromium/storage/browser/blob/blob_reader.cc index 43735ce4722..3e8ade6a57f 100644 --- a/chromium/storage/browser/blob/blob_reader.cc +++ b/chromium/storage/browser/blob/blob_reader.cc @@ -6,11 +6,14 @@ #include <stddef.h> #include <stdint.h> + #include <algorithm> #include <limits> +#include <memory> #include <utility> #include "base/bind.h" +#include "base/callback_helpers.h" #include "base/sequenced_task_runner.h" #include "base/stl_util.h" #include "base/time/time.h" @@ -36,20 +39,39 @@ bool IsFileType(DataElement::Type type) { return false; } } + +int ConvertBlobErrorToNetError(IPCBlobCreationCancelCode reason) { + switch (reason) { + case IPCBlobCreationCancelCode::UNKNOWN: + return net::ERR_FAILED; + case IPCBlobCreationCancelCode::OUT_OF_MEMORY: + return net::ERR_OUT_OF_MEMORY; + case IPCBlobCreationCancelCode::FILE_WRITE_FAILED: + return net::ERR_FILE_NO_SPACE; + case IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT: + return net::ERR_UNEXPECTED; + case IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING: + return net::ERR_UNEXPECTED; + case IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN: + return net::ERR_INVALID_HANDLE; + } + NOTREACHED(); + return net::ERR_FAILED; +} } // namespace BlobReader::FileStreamReaderProvider::~FileStreamReaderProvider() {} BlobReader::BlobReader( const BlobDataHandle* blob_handle, - scoped_ptr<FileStreamReaderProvider> file_stream_provider, + std::unique_ptr<FileStreamReaderProvider> file_stream_provider, base::SequencedTaskRunner* file_task_runner) : file_stream_provider_(std::move(file_stream_provider)), file_task_runner_(file_task_runner), net_error_(net::OK), weak_factory_(this) { - if (blob_handle) { - blob_data_ = blob_handle->CreateSnapshot(); + if (blob_handle && !blob_handle->IsBroken()) { + blob_handle_.reset(new BlobDataHandle(*blob_handle)); } } @@ -61,58 +83,20 @@ BlobReader::Status BlobReader::CalculateSize( const net::CompletionCallback& done) { DCHECK(!total_size_calculated_); DCHECK(size_callback_.is_null()); - if (!blob_data_.get()) { + if (!blob_handle_.get() || blob_handle_->IsBroken()) { return ReportError(net::ERR_FILE_NOT_FOUND); } - - net_error_ = net::OK; - total_size_ = 0; - const auto& items = blob_data_->items(); - item_length_list_.resize(items.size()); - pending_get_file_info_count_ = 0; - for (size_t i = 0; i < items.size(); ++i) { - const BlobDataItem& item = *items.at(i); - if (IsFileType(item.type())) { - ++pending_get_file_info_count_; - storage::FileStreamReader* const reader = GetOrCreateFileReaderAtIndex(i); - if (!reader) { - return ReportError(net::ERR_FAILED); - } - int64_t length_output = reader->GetLength(base::Bind( - &BlobReader::DidGetFileItemLength, weak_factory_.GetWeakPtr(), i)); - if (length_output == net::ERR_IO_PENDING) { - continue; - } - if (length_output < 0) { - return ReportError(length_output); - } - // We got the length right away - --pending_get_file_info_count_; - uint64_t resolved_length; - if (!ResolveFileItemLength(item, length_output, &resolved_length)) { - return ReportError(net::ERR_FILE_NOT_FOUND); - } - if (!AddItemLength(i, resolved_length)) { - return ReportError(net::ERR_FAILED); - } - continue; - } - - if (!AddItemLength(i, item.length())) - return ReportError(net::ERR_FAILED); - } - - if (pending_get_file_info_count_ == 0) { - DidCountSize(); - return Status::DONE; + if (blob_handle_->IsBeingBuilt()) { + blob_handle_->RunOnConstructionComplete(base::Bind( + &BlobReader::AsyncCalculateSize, weak_factory_.GetWeakPtr(), done)); + return Status::IO_PENDING; } - // Note: We only set the callback if we know that we're an async operation. - size_callback_ = done; - return Status::IO_PENDING; + blob_data_ = blob_handle_->CreateSnapshot(); + return CalculateSizeImpl(done); } BlobReader::Status BlobReader::SetReadRange(uint64_t offset, uint64_t length) { - if (!blob_data_.get()) { + if (!blob_handle_.get() || blob_handle_->IsBroken()) { return ReportError(net::ERR_FILE_NOT_FOUND); } if (!total_size_calculated_) { @@ -219,6 +203,79 @@ BlobReader::Status BlobReader::ReportError(int net_error) { return Status::NET_ERROR; } +void BlobReader::AsyncCalculateSize(const net::CompletionCallback& done, + bool async_succeeded, + IPCBlobCreationCancelCode reason) { + if (!async_succeeded) { + InvalidateCallbacksAndDone(ConvertBlobErrorToNetError(reason), done); + return; + } + DCHECK(!blob_handle_->IsBroken()) << "Callback should have returned false."; + blob_data_ = blob_handle_->CreateSnapshot(); + Status size_status = CalculateSizeImpl(done); + switch (size_status) { + case Status::NET_ERROR: + InvalidateCallbacksAndDone(net_error_, done); + return; + case Status::DONE: + done.Run(net::OK); + return; + case Status::IO_PENDING: + return; + } +} + +BlobReader::Status BlobReader::CalculateSizeImpl( + const net::CompletionCallback& done) { + DCHECK(!total_size_calculated_); + DCHECK(size_callback_.is_null()); + + net_error_ = net::OK; + total_size_ = 0; + const auto& items = blob_data_->items(); + item_length_list_.resize(items.size()); + pending_get_file_info_count_ = 0; + for (size_t i = 0; i < items.size(); ++i) { + const BlobDataItem& item = *items.at(i); + if (IsFileType(item.type())) { + ++pending_get_file_info_count_; + storage::FileStreamReader* const reader = GetOrCreateFileReaderAtIndex(i); + if (!reader) { + return ReportError(net::ERR_FAILED); + } + int64_t length_output = reader->GetLength(base::Bind( + &BlobReader::DidGetFileItemLength, weak_factory_.GetWeakPtr(), i)); + if (length_output == net::ERR_IO_PENDING) { + continue; + } + if (length_output < 0) { + return ReportError(length_output); + } + // We got the length right away + --pending_get_file_info_count_; + uint64_t resolved_length; + if (!ResolveFileItemLength(item, length_output, &resolved_length)) { + return ReportError(net::ERR_FILE_NOT_FOUND); + } + if (!AddItemLength(i, resolved_length)) { + return ReportError(net::ERR_FAILED); + } + continue; + } + + if (!AddItemLength(i, item.length())) + return ReportError(net::ERR_FAILED); + } + + if (pending_get_file_info_count_ == 0) { + DidCountSize(); + return Status::DONE; + } + // Note: We only set the callback if we know that we're an async operation. + size_callback_ = done; + return Status::IO_PENDING; +} + bool BlobReader::AddItemLength(size_t index, uint64_t item_length) { if (item_length > std::numeric_limits<uint64_t>::max() - total_size_) { return false; @@ -437,7 +494,8 @@ void BlobReader::ContinueAsyncReadLoop() { } void BlobReader::DeleteCurrentFileReader() { - SetFileReaderAtIndex(current_item_index_, scoped_ptr<FileStreamReader>()); + SetFileReaderAtIndex(current_item_index_, + std::unique_ptr<FileStreamReader>()); } BlobReader::Status BlobReader::ReadDiskCacheEntryItem(const BlobDataItem& item, @@ -512,7 +570,7 @@ FileStreamReader* BlobReader::GetOrCreateFileReaderAtIndex(size_t index) { DCHECK(it->second); return it->second; } - scoped_ptr<FileStreamReader> reader = CreateFileStreamReader(item, 0); + std::unique_ptr<FileStreamReader> reader = CreateFileStreamReader(item, 0); FileStreamReader* ret_value = reader.get(); if (!ret_value) return nullptr; @@ -520,7 +578,7 @@ FileStreamReader* BlobReader::GetOrCreateFileReaderAtIndex(size_t index) { return ret_value; } -scoped_ptr<FileStreamReader> BlobReader::CreateFileStreamReader( +std::unique_ptr<FileStreamReader> BlobReader::CreateFileStreamReader( const BlobDataItem& item, uint64_t additional_offset) { DCHECK(IsFileType(item.type())); @@ -549,8 +607,9 @@ scoped_ptr<FileStreamReader> BlobReader::CreateFileStreamReader( return nullptr; } -void BlobReader::SetFileReaderAtIndex(size_t index, - scoped_ptr<FileStreamReader> reader) { +void BlobReader::SetFileReaderAtIndex( + size_t index, + std::unique_ptr<FileStreamReader> reader) { auto found = index_to_reader_.find(current_item_index_); if (found != index_to_reader_.end()) { if (found->second) { diff --git a/chromium/storage/browser/blob/blob_reader.h b/chromium/storage/browser/blob/blob_reader.h index 0756f0fc1cf..57943832a5f 100644 --- a/chromium/storage/browser/blob/blob_reader.h +++ b/chromium/storage/browser/blob/blob_reader.h @@ -7,14 +7,17 @@ #include <stddef.h> #include <stdint.h> + #include <map> +#include <memory> #include <vector> +#include "base/gtest_prod_util.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "net/base/completion_callback.h" #include "storage/browser/storage_browser_export.h" +#include "storage/common/blob_storage/blob_storage_constants.h" class GURL; @@ -49,13 +52,13 @@ class STORAGE_EXPORT BlobReader { public: virtual ~FileStreamReaderProvider(); - virtual scoped_ptr<FileStreamReader> CreateForLocalFile( + virtual std::unique_ptr<FileStreamReader> CreateForLocalFile( base::TaskRunner* task_runner, const base::FilePath& file_path, int64_t initial_offset, const base::Time& expected_modification_time) = 0; - virtual scoped_ptr<FileStreamReader> CreateFileStreamReader( + virtual std::unique_ptr<FileStreamReader> CreateFileStreamReader( const GURL& filesystem_url, int64_t offset, int64_t max_bytes_to_read, @@ -108,14 +111,19 @@ class STORAGE_EXPORT BlobReader { // Returns the total size of the blob. This is populated after CalculateSize // is called. - uint64_t total_size() const { return total_size_; } + uint64_t total_size() const { + DCHECK(total_size_calculated_); + return total_size_; + } protected: friend class BlobDataHandle; friend class BlobReaderTest; + FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, HandleBeforeAsyncCancel); + FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, ReadFromIncompleteBlob); BlobReader(const BlobDataHandle* blob_handle, - scoped_ptr<FileStreamReaderProvider> file_stream_provider, + std::unique_ptr<FileStreamReaderProvider> file_stream_provider, base::SequencedTaskRunner* file_task_runner); bool total_size_calculated() const { return total_size_calculated_; } @@ -124,6 +132,10 @@ class STORAGE_EXPORT BlobReader { Status ReportError(int net_error); void InvalidateCallbacksAndDone(int net_error, net::CompletionCallback done); + void AsyncCalculateSize(const net::CompletionCallback& done, + bool async_succeeded, + IPCBlobCreationCancelCode reason); + Status CalculateSizeImpl(const net::CompletionCallback& done); bool AddItemLength(size_t index, uint64_t length); bool ResolveFileItemLength(const BlobDataItem& item, int64_t total_length, @@ -154,14 +166,16 @@ class STORAGE_EXPORT BlobReader { // If the item at |index| is not of file this returns NULL. FileStreamReader* GetOrCreateFileReaderAtIndex(size_t index); // If the reader is null, then this basically performs a delete operation. - void SetFileReaderAtIndex(size_t index, scoped_ptr<FileStreamReader> reader); + void SetFileReaderAtIndex(size_t index, + std::unique_ptr<FileStreamReader> reader); // Creates a FileStreamReader for the item with additional_offset. - scoped_ptr<FileStreamReader> CreateFileStreamReader( + std::unique_ptr<FileStreamReader> CreateFileStreamReader( const BlobDataItem& item, uint64_t additional_offset); - scoped_ptr<BlobDataSnapshot> blob_data_; - scoped_ptr<FileStreamReaderProvider> file_stream_provider_; + std::unique_ptr<BlobDataHandle> blob_handle_; + std::unique_ptr<BlobDataSnapshot> blob_data_; + std::unique_ptr<FileStreamReaderProvider> file_stream_provider_; scoped_refptr<base::SequencedTaskRunner> file_task_runner_; int net_error_; diff --git a/chromium/storage/browser/blob/blob_storage_context.cc b/chromium/storage/browser/blob/blob_storage_context.cc index e8fc0085cdf..5beb1a52eb4 100644 --- a/chromium/storage/browser/blob/blob_storage_context.cc +++ b/chromium/storage/browser/blob/blob_storage_context.cc @@ -6,123 +6,73 @@ #include <stddef.h> #include <stdint.h> + #include <algorithm> #include <limits> +#include <memory> #include <utility> #include "base/bind.h" +#include "base/callback.h" #include "base/location.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" -#include "base/stl_util.h" #include "base/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "storage/browser/blob/blob_data_builder.h" -#include "storage/browser/blob/shareable_file_reference.h" +#include "storage/browser/blob/blob_data_handle.h" +#include "storage/browser/blob/blob_data_item.h" +#include "storage/browser/blob/blob_data_snapshot.h" +#include "storage/browser/blob/shareable_blob_data_item.h" #include "url/gurl.h" namespace storage { +using BlobRegistryEntry = BlobStorageRegistry::Entry; +using BlobState = BlobStorageRegistry::BlobState; -namespace { - -// We can't use GURL directly for these hash fragment manipulations -// since it doesn't have specific knowlege of the BlobURL format. GURL -// treats BlobURLs as if they were PathURLs which don't support hash -// fragments. - -bool BlobUrlHasRef(const GURL& url) { - return url.spec().find('#') != std::string::npos; -} - -GURL ClearBlobUrlRef(const GURL& url) { - size_t hash_pos = url.spec().find('#'); - if (hash_pos == std::string::npos) - return url; - return GURL(url.spec().substr(0, hash_pos)); -} - -// TODO(michaeln): use base::SysInfo::AmountOfPhysicalMemoryMB() in some -// way to come up with a better limit. -static const int64_t kMaxMemoryUsage = 500 * 1024 * 1024; // Half a gig. - -} // namespace - -BlobStorageContext::BlobMapEntry::BlobMapEntry() : refcount(0), flags(0) { -} - -BlobStorageContext::BlobMapEntry::BlobMapEntry(int refcount, - InternalBlobData::Builder* data) - : refcount(refcount), flags(0), data_builder(data) { -} - -BlobStorageContext::BlobMapEntry::~BlobMapEntry() { -} - -bool BlobStorageContext::BlobMapEntry::IsBeingBuilt() { - return data_builder; -} - -BlobStorageContext::BlobStorageContext() : memory_usage_(0) { -} +BlobStorageContext::BlobStorageContext() : memory_usage_(0) {} BlobStorageContext::~BlobStorageContext() { - STLDeleteContainerPairSecondPointers(blob_map_.begin(), blob_map_.end()); } -scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID( +std::unique_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID( const std::string& uuid) { - scoped_ptr<BlobDataHandle> result; - BlobMap::iterator found = blob_map_.find(uuid); - if (found == blob_map_.end()) - return result; - auto* entry = found->second; - if (entry->flags & EXCEEDED_MEMORY) - return result; - DCHECK(!entry->IsBeingBuilt()); - result.reset(new BlobDataHandle(uuid, entry->data->content_type(), - entry->data->content_disposition(), this, - base::ThreadTaskRunnerHandle::Get().get())); - return result; + BlobRegistryEntry* entry = registry_.GetEntry(uuid); + if (!entry) { + return nullptr; + } + return base::WrapUnique( + new BlobDataHandle(uuid, entry->content_type, entry->content_disposition, + this, base::ThreadTaskRunnerHandle::Get().get())); } -scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL( +std::unique_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL( const GURL& url) { - BlobURLMap::iterator found = - public_blob_urls_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url); - if (found == public_blob_urls_.end()) - return scoped_ptr<BlobDataHandle>(); - return GetBlobDataFromUUID(found->second); + std::string uuid; + BlobRegistryEntry* entry = registry_.GetEntryFromURL(url, &uuid); + if (!entry) { + return nullptr; + } + return base::WrapUnique( + new BlobDataHandle(uuid, entry->content_type, entry->content_disposition, + this, base::ThreadTaskRunnerHandle::Get().get())); } -scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( +std::unique_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( const BlobDataBuilder& external_builder) { TRACE_EVENT0("Blob", "Context::AddFinishedBlob"); - StartBuildingBlob(external_builder.uuid_); - BlobMap::iterator found = blob_map_.find(external_builder.uuid_); - DCHECK(found != blob_map_.end()); - BlobMapEntry* entry = found->second; - InternalBlobData::Builder* target_blob_builder = entry->data_builder.get(); - DCHECK(target_blob_builder); - - target_blob_builder->set_content_disposition( - external_builder.content_disposition_); - for (const auto& blob_item : external_builder.items_) { - if (!AppendAllocatedBlobItem(external_builder.uuid_, blob_item, - target_blob_builder)) { - BlobEntryExceededMemory(entry); - break; - } - } - - FinishBuildingBlob(external_builder.uuid_, external_builder.content_type_); - scoped_ptr<BlobDataHandle> handle = + CreatePendingBlob(external_builder.uuid(), external_builder.content_type_, + external_builder.content_disposition_); + CompletePendingBlob(external_builder); + std::unique_ptr<BlobDataHandle> handle = GetBlobDataFromUUID(external_builder.uuid_); DecrementBlobRefCount(external_builder.uuid_); return handle; } -scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( +std::unique_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( const BlobDataBuilder* builder) { DCHECK(builder); return AddFinishedBlob(*builder); @@ -130,185 +80,186 @@ scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( bool BlobStorageContext::RegisterPublicBlobURL(const GURL& blob_url, const std::string& uuid) { - DCHECK(!BlobUrlHasRef(blob_url)); - DCHECK(IsInUse(uuid)); - DCHECK(!IsUrlRegistered(blob_url)); - if (!IsInUse(uuid) || IsUrlRegistered(blob_url)) + if (!registry_.CreateUrlMapping(blob_url, uuid)) { return false; + } IncrementBlobRefCount(uuid); - public_blob_urls_[blob_url] = uuid; return true; } void BlobStorageContext::RevokePublicBlobURL(const GURL& blob_url) { - DCHECK(!BlobUrlHasRef(blob_url)); - if (!IsUrlRegistered(blob_url)) + std::string uuid; + if (!registry_.DeleteURLMapping(blob_url, &uuid)) { return; - DecrementBlobRefCount(public_blob_urls_[blob_url]); - public_blob_urls_.erase(blob_url); -} - -scoped_ptr<BlobDataSnapshot> BlobStorageContext::CreateSnapshot( - const std::string& uuid) { - scoped_ptr<BlobDataSnapshot> result; - auto found = blob_map_.find(uuid); - DCHECK(found != blob_map_.end()) - << "Blob " << uuid << " should be in map, as the handle is still around"; - BlobMapEntry* entry = found->second; - DCHECK(!entry->IsBeingBuilt()); - const InternalBlobData& data = *entry->data; - - scoped_ptr<BlobDataSnapshot> snapshot(new BlobDataSnapshot( - uuid, data.content_type(), data.content_disposition())); - snapshot->items_.reserve(data.items().size()); - for (const auto& shareable_item : data.items()) { - snapshot->items_.push_back(shareable_item->item()); } - return snapshot; -} - -void BlobStorageContext::StartBuildingBlob(const std::string& uuid) { - DCHECK(!IsInUse(uuid) && !uuid.empty()); - blob_map_[uuid] = new BlobMapEntry(1, new InternalBlobData::Builder()); + DecrementBlobRefCount(uuid); } -void BlobStorageContext::AppendBlobDataItem( +void BlobStorageContext::CreatePendingBlob( const std::string& uuid, - const storage::DataElement& ipc_data_element) { - TRACE_EVENT0("Blob", "Context::AppendBlobDataItem"); - DCHECK(IsBeingBuilt(uuid)); - BlobMap::iterator found = blob_map_.find(uuid); - if (found == blob_map_.end()) - return; - BlobMapEntry* entry = found->second; - if (entry->flags & EXCEEDED_MEMORY) - return; - InternalBlobData::Builder* target_blob_builder = entry->data_builder.get(); - DCHECK(target_blob_builder); + const std::string& content_type, + const std::string& content_disposition) { + DCHECK(!registry_.GetEntry(uuid) && !uuid.empty()); + registry_.CreateEntry(uuid, content_type, content_disposition); +} - if (ipc_data_element.type() == DataElement::TYPE_BYTES && - memory_usage_ + ipc_data_element.length() > kMaxMemoryUsage) { - BlobEntryExceededMemory(entry); - return; - } - if (!AppendAllocatedBlobItem(uuid, AllocateBlobItem(uuid, ipc_data_element), - target_blob_builder)) { - BlobEntryExceededMemory(entry); +void BlobStorageContext::CompletePendingBlob( + const BlobDataBuilder& external_builder) { + BlobRegistryEntry* entry = registry_.GetEntry(external_builder.uuid()); + DCHECK(entry); + DCHECK(!entry->data.get()) << "Blob already constructed: " + << external_builder.uuid(); + // We want to handle storing our broken blob as well. + switch (entry->state) { + case BlobState::PENDING: { + entry->data_builder.reset(new InternalBlobData::Builder()); + InternalBlobData::Builder* internal_data_builder = + entry->data_builder.get(); + + bool broken = false; + for (const auto& blob_item : external_builder.items_) { + IPCBlobCreationCancelCode error_code; + if (!AppendAllocatedBlobItem(external_builder.uuid_, blob_item, + internal_data_builder, &error_code)) { + broken = true; + memory_usage_ -= entry->data_builder->GetNonsharedMemoryUsage(); + entry->state = BlobState::BROKEN; + entry->broken_reason = error_code; + entry->data_builder.reset(new InternalBlobData::Builder()); + break; + } + } + entry->data = entry->data_builder->Build(); + entry->data_builder.reset(); + entry->state = broken ? BlobState::BROKEN : BlobState::COMPLETE; + break; + } + case BlobState::BROKEN: { + InternalBlobData::Builder builder; + entry->data = builder.Build(); + break; + } + case BlobState::COMPLETE: + DCHECK(false) << "Blob already constructed: " << external_builder.uuid(); + return; } -} -void BlobStorageContext::FinishBuildingBlob(const std::string& uuid, - const std::string& content_type) { - DCHECK(IsBeingBuilt(uuid)); - BlobMap::iterator found = blob_map_.find(uuid); - if (found == blob_map_.end()) - return; - BlobMapEntry* entry = found->second; - entry->data_builder->set_content_type(content_type); - entry->data = entry->data_builder->Build(); - entry->data_builder.reset(); UMA_HISTOGRAM_COUNTS("Storage.Blob.ItemCount", entry->data->items().size()); - UMA_HISTOGRAM_BOOLEAN("Storage.Blob.ExceededMemory", - (entry->flags & EXCEEDED_MEMORY) == EXCEEDED_MEMORY); + UMA_HISTOGRAM_BOOLEAN("Storage.Blob.Broken", + entry->state == BlobState::BROKEN); + if (entry->state == BlobState::BROKEN) { + UMA_HISTOGRAM_ENUMERATION( + "Storage.Blob.BrokenReason", static_cast<int>(entry->broken_reason), + (static_cast<int>(IPCBlobCreationCancelCode::LAST) + 1)); + } size_t total_memory = 0, nonshared_memory = 0; entry->data->GetMemoryUsage(&total_memory, &nonshared_memory); UMA_HISTOGRAM_COUNTS("Storage.Blob.TotalSize", total_memory / 1024); UMA_HISTOGRAM_COUNTS("Storage.Blob.TotalUnsharedSize", nonshared_memory / 1024); TRACE_COUNTER1("Blob", "MemoryStoreUsageBytes", memory_usage_); + + auto runner = base::ThreadTaskRunnerHandle::Get(); + for (const auto& callback : entry->build_completion_callbacks) { + runner->PostTask(FROM_HERE, + base::Bind(callback, entry->state == BlobState::COMPLETE, + entry->broken_reason)); + } + entry->build_completion_callbacks.clear(); } -void BlobStorageContext::CancelBuildingBlob(const std::string& uuid) { - DCHECK(IsBeingBuilt(uuid)); - DecrementBlobRefCount(uuid); +void BlobStorageContext::CancelPendingBlob(const std::string& uuid, + IPCBlobCreationCancelCode reason) { + BlobRegistryEntry* entry = registry_.GetEntry(uuid); + DCHECK(entry && entry->state == BlobState::PENDING); + entry->state = BlobState::BROKEN; + entry->broken_reason = reason; + CompletePendingBlob(BlobDataBuilder(uuid)); } void BlobStorageContext::IncrementBlobRefCount(const std::string& uuid) { - BlobMap::iterator found = blob_map_.find(uuid); - if (found == blob_map_.end()) { - DCHECK(false); - return; - } - ++(found->second->refcount); + BlobRegistryEntry* entry = registry_.GetEntry(uuid); + DCHECK(entry); + ++(entry->refcount); } void BlobStorageContext::DecrementBlobRefCount(const std::string& uuid) { - BlobMap::iterator found = blob_map_.find(uuid); - if (found == blob_map_.end()) - return; - auto* entry = found->second; + BlobRegistryEntry* entry = registry_.GetEntry(uuid); + DCHECK(entry); + DCHECK_GT(entry->refcount, 0u); if (--(entry->refcount) == 0) { size_t memory_freeing = 0; - if (entry->IsBeingBuilt()) { - memory_freeing = entry->data_builder->GetNonsharedMemoryUsage(); - entry->data_builder->RemoveBlobFromShareableItems(uuid); - } else { + if (entry->state == BlobState::COMPLETE) { memory_freeing = entry->data->GetUnsharedMemoryUsage(); entry->data->RemoveBlobFromShareableItems(uuid); } DCHECK_LE(memory_freeing, memory_usage_); memory_usage_ -= memory_freeing; - delete entry; - blob_map_.erase(found); + registry_.DeleteEntry(uuid); } } -void BlobStorageContext::BlobEntryExceededMemory(BlobMapEntry* entry) { - // If we're using too much memory, drop this blob's data. - // TODO(michaeln): Blob memory storage does not yet spill over to disk, - // as a stop gap, we'll prevent memory usage over a max amount. - memory_usage_ -= entry->data_builder->GetNonsharedMemoryUsage(); - entry->flags |= EXCEEDED_MEMORY; - entry->data_builder.reset(new InternalBlobData::Builder()); +std::unique_ptr<BlobDataSnapshot> BlobStorageContext::CreateSnapshot( + const std::string& uuid) { + std::unique_ptr<BlobDataSnapshot> result; + BlobRegistryEntry* entry = registry_.GetEntry(uuid); + if (entry->state != BlobState::COMPLETE) { + return result; + } + + const InternalBlobData& data = *entry->data; + std::unique_ptr<BlobDataSnapshot> snapshot(new BlobDataSnapshot( + uuid, entry->content_type, entry->content_disposition)); + snapshot->items_.reserve(data.items().size()); + for (const auto& shareable_item : data.items()) { + snapshot->items_.push_back(shareable_item->item()); + } + return snapshot; } -scoped_refptr<BlobDataItem> BlobStorageContext::AllocateBlobItem( - const std::string& uuid, - const DataElement& ipc_data) { - scoped_refptr<BlobDataItem> blob_item; +bool BlobStorageContext::IsBroken(const std::string& uuid) const { + const BlobRegistryEntry* entry = registry_.GetEntry(uuid); + if (!entry) { + return true; + } + return entry->state == BlobState::BROKEN; +} - uint64_t length = ipc_data.length(); - scoped_ptr<DataElement> element(new DataElement()); - switch (ipc_data.type()) { - case DataElement::TYPE_BYTES: - DCHECK(!ipc_data.offset()); - element->SetToBytes(ipc_data.bytes(), length); - blob_item = new BlobDataItem(std::move(element)); - break; - case DataElement::TYPE_FILE: - element->SetToFilePathRange(ipc_data.path(), ipc_data.offset(), length, - ipc_data.expected_modification_time()); - blob_item = new BlobDataItem( - std::move(element), ShareableFileReference::Get(ipc_data.path())); - break; - case DataElement::TYPE_FILE_FILESYSTEM: - element->SetToFileSystemUrlRange(ipc_data.filesystem_url(), - ipc_data.offset(), length, - ipc_data.expected_modification_time()); - blob_item = new BlobDataItem(std::move(element)); - break; - case DataElement::TYPE_BLOB: - // This is a temporary item that will be deconstructed later. - element->SetToBlobRange(ipc_data.blob_uuid(), ipc_data.offset(), - ipc_data.length()); - blob_item = new BlobDataItem(std::move(element)); - break; - case DataElement::TYPE_DISK_CACHE_ENTRY: // This type can't be sent by IPC. - NOTREACHED(); - break; - default: - NOTREACHED(); - break; +bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) const { + const BlobRegistryEntry* entry = registry_.GetEntry(uuid); + if (!entry) { + return false; } + return entry->state == BlobState::PENDING; +} - return blob_item; +void BlobStorageContext::RunOnConstructionComplete( + const std::string& uuid, + const BlobConstructedCallback& done) { + BlobRegistryEntry* entry = registry_.GetEntry(uuid); + DCHECK(entry); + switch (entry->state) { + case BlobState::COMPLETE: + done.Run(true, IPCBlobCreationCancelCode::UNKNOWN); + return; + case BlobState::BROKEN: + done.Run(false, entry->broken_reason); + return; + case BlobState::PENDING: + entry->build_completion_callbacks.push_back(done); + return; + } + NOTREACHED(); } bool BlobStorageContext::AppendAllocatedBlobItem( const std::string& target_blob_uuid, scoped_refptr<BlobDataItem> blob_item, - InternalBlobData::Builder* target_blob_builder) { - bool exceeded_memory = false; + InternalBlobData::Builder* target_blob_builder, + IPCBlobCreationCancelCode* error_code) { + DCHECK(error_code); + *error_code = IPCBlobCreationCancelCode::UNKNOWN; + bool error = false; // The blob data is stored in the canonical way which only contains a // list of Data, File, and FileSystem items. Aggregated TYPE_BLOB items @@ -323,6 +274,7 @@ bool BlobStorageContext::AppendAllocatedBlobItem( // offset or size) are shared between the blobs. Otherwise, the relevant // portion of the item is copied. + DCHECK(blob_item->data_element_ptr()); const DataElement& data_element = blob_item->data_element(); uint64_t length = data_element.length(); uint64_t offset = data_element.offset(); @@ -332,8 +284,9 @@ bool BlobStorageContext::AppendAllocatedBlobItem( case DataElement::TYPE_BYTES: UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Bytes", length / 1024); DCHECK(!offset); - if (memory_usage_ + length > kMaxMemoryUsage) { - exceeded_memory = true; + if (memory_usage_ + length > kBlobStorageMaxMemoryUsage) { + error = true; + *error_code = IPCBlobCreationCancelCode::OUT_OF_MEMORY; break; } memory_usage_ += length; @@ -367,14 +320,20 @@ bool BlobStorageContext::AppendAllocatedBlobItem( UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Blob", (length - offset) / 1024); // We grab the handle to ensure it stays around while we copy it. - scoped_ptr<BlobDataHandle> src = + std::unique_ptr<BlobDataHandle> src = GetBlobDataFromUUID(data_element.blob_uuid()); - if (src) { - BlobMapEntry* other_entry = - blob_map_.find(data_element.blob_uuid())->second; - DCHECK(other_entry->data); - exceeded_memory = !AppendBlob(target_blob_uuid, *other_entry->data, - offset, length, target_blob_builder); + if (!src || src->IsBroken() || src->IsBeingBuilt()) { + error = true; + *error_code = IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN; + break; + } + BlobRegistryEntry* other_entry = + registry_.GetEntry(data_element.blob_uuid()); + DCHECK(other_entry->data); + if (!AppendBlob(target_blob_uuid, *other_entry->data, offset, length, + target_blob_builder)) { + error = true; + *error_code = IPCBlobCreationCancelCode::OUT_OF_MEMORY; } break; } @@ -385,14 +344,14 @@ bool BlobStorageContext::AppendAllocatedBlobItem( new ShareableBlobDataItem(target_blob_uuid, blob_item)); break; } - default: + case DataElement::TYPE_BYTES_DESCRIPTION: + case DataElement::TYPE_UNKNOWN: NOTREACHED(); break; } UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeAfterAppend", memory_usage_ / 1024); - - return !exceeded_memory; + return !error; } bool BlobStorageContext::AppendBlob( @@ -401,7 +360,7 @@ bool BlobStorageContext::AppendBlob( uint64_t offset, uint64_t length, InternalBlobData::Builder* target_blob_builder) { - DCHECK(length > 0); + DCHECK_GT(length, 0ull); const std::vector<scoped_refptr<ShareableBlobDataItem>>& items = blob.items(); auto iter = items.begin(); @@ -438,11 +397,11 @@ bool BlobStorageContext::AppendBlob( case DataElement::TYPE_BYTES: { UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.Bytes", new_length / 1024); - if (memory_usage_ + new_length > kMaxMemoryUsage) { + if (memory_usage_ + new_length > kBlobStorageMaxMemoryUsage) { return false; } DCHECK(!item.offset()); - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToBytes(item.bytes() + offset, static_cast<int64_t>(new_length)); memory_usage_ += new_length; @@ -454,7 +413,7 @@ bool BlobStorageContext::AppendBlob( << "We cannot use a section of a file with an unknown length"; UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.File", new_length / 1024); - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToFilePathRange(item.path(), item.offset() + offset, new_length, item.expected_modification_time()); @@ -465,7 +424,7 @@ bool BlobStorageContext::AppendBlob( case DataElement::TYPE_FILE_FILESYSTEM: { UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.FileSystem", new_length / 1024); - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToFileSystemUrlRange(item.filesystem_url(), item.offset() + offset, new_length, item.expected_modification_time()); @@ -473,7 +432,7 @@ bool BlobStorageContext::AppendBlob( target_blob_uuid, new BlobDataItem(std::move(element)))); } break; case DataElement::TYPE_DISK_CACHE_ENTRY: { - scoped_ptr<DataElement> element(new DataElement()); + std::unique_ptr<DataElement> element(new DataElement()); element->SetToDiskCacheEntryRange(item.offset() + offset, new_length); target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( @@ -482,7 +441,9 @@ bool BlobStorageContext::AppendBlob( item.disk_cache_entry(), item.disk_cache_stream_index()))); } break; - default: + case DataElement::TYPE_BYTES_DESCRIPTION: + case DataElement::TYPE_BLOB: + case DataElement::TYPE_UNKNOWN: CHECK(false) << "Illegal blob item type: " << item.type(); } length -= new_length; @@ -491,19 +452,4 @@ bool BlobStorageContext::AppendBlob( return true; } -bool BlobStorageContext::IsInUse(const std::string& uuid) { - return blob_map_.find(uuid) != blob_map_.end(); -} - -bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) { - BlobMap::iterator found = blob_map_.find(uuid); - if (found == blob_map_.end()) - return false; - return found->second->IsBeingBuilt(); -} - -bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) { - return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); -} - } // namespace storage diff --git a/chromium/storage/browser/blob/blob_storage_context.h b/chromium/storage/browser/blob/blob_storage_context.h index 54cff9b2a86..8553d0266d2 100644 --- a/chromium/storage/browser/blob/blob_storage_context.h +++ b/chromium/storage/browser/blob/blob_storage_context.h @@ -9,18 +9,20 @@ #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_data_item.h" -#include "storage/browser/blob/blob_data_snapshot.h" +#include "storage/browser/blob/blob_storage_registry.h" #include "storage/browser/blob/internal_blob_data.h" -#include "storage/browser/blob/shareable_blob_data_item.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; @@ -31,13 +33,16 @@ class Time; } namespace content { -class BlobStorageHost; +class BlobDispatcherHost; +class BlobDispatcherHostTest; } namespace storage { class BlobDataBuilder; -class InternalBlobData; +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 @@ -49,8 +54,8 @@ class STORAGE_EXPORT BlobStorageContext BlobStorageContext(); ~BlobStorageContext(); - scoped_ptr<BlobDataHandle> GetBlobDataFromUUID(const std::string& uuid); - scoped_ptr<BlobDataHandle> GetBlobDataFromPublicURL(const GURL& url); + 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. @@ -59,70 +64,88 @@ class STORAGE_EXPORT BlobStorageContext // 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. - scoped_ptr<BlobDataHandle> AddFinishedBlob(const BlobDataBuilder& builder); + std::unique_ptr<BlobDataHandle> AddFinishedBlob( + const BlobDataBuilder& builder); // Deprecated, use const ref version above. - scoped_ptr<BlobDataHandle> AddFinishedBlob(const BlobDataBuilder* builder); + 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 blob_map_.size(); } + size_t blob_count() const { return registry_.blob_count(); } + size_t memory_available() const { + return kBlobStorageMaxMemoryUsage - memory_usage_; + } + + const BlobStorageRegistry& registry() { return registry_; } private: - friend class content::BlobStorageHost; + 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_TEST_ALL_PREFIXES(BlobStorageContextTest, + TestUnknownBrokenAndBuildingBlobReference); friend class ViewBlobInternalsJob; - enum EntryFlags { - EXCEEDED_MEMORY = 1 << 1, - }; - - struct BlobMapEntry { - int refcount; - int flags; - // data and data_builder are mutually exclusive. - scoped_ptr<InternalBlobData> data; - scoped_ptr<InternalBlobData::Builder> data_builder; - - BlobMapEntry(); - BlobMapEntry(int refcount, InternalBlobData::Builder* data); - ~BlobMapEntry(); - - bool IsBeingBuilt(); - }; + // CompletePendingBlob or CancelPendingBlob should be called after this. + void CreatePendingBlob(const std::string& uuid, + const std::string& content_type, + const std::string& content_disposition); - typedef std::map<std::string, BlobMapEntry*> BlobMap; - typedef std::map<GURL, std::string> BlobURLMap; + // This includes resolving blob references in the builder. This will run the + // callbacks given in RunOnConstructionComplete. + void CompletePendingBlob(const BlobDataBuilder& external_builder); - // Called by BlobDataHandle. - scoped_ptr<BlobDataSnapshot> CreateSnapshot(const std::string& uuid); + // This will run the callbacks given in RunOnConstructionComplete. + void CancelPendingBlob(const std::string& uuid, + IPCBlobCreationCancelCode reason); - // ### Methods called by BlobStorageHost ### - void StartBuildingBlob(const std::string& uuid); - void AppendBlobDataItem(const std::string& uuid, - const DataElement& data_item); - void FinishBuildingBlob(const std::string& uuid, const std::string& type); - void CancelBuildingBlob(const std::string& uuid); void IncrementBlobRefCount(const std::string& uuid); void DecrementBlobRefCount(const std::string& uuid); - // ######################################### - // Flags the entry for exceeding memory, and resets the builder. - void BlobEntryExceededMemory(BlobMapEntry* entry); - - // Allocates memory to hold the given data element and copies the data over. - scoped_refptr<BlobDataItem> AllocateBlobItem(const std::string& uuid, - const DataElement& data_item); + // 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 - // wasn't enough memory to hold the item. + // 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); + 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 @@ -133,12 +156,7 @@ class STORAGE_EXPORT BlobStorageContext uint64_t length, InternalBlobData::Builder* target_blob_data); - bool IsInUse(const std::string& uuid); - bool IsBeingBuilt(const std::string& uuid); - bool IsUrlRegistered(const GURL& blob_url); - - BlobMap blob_map_; - BlobURLMap public_blob_urls_; + 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 diff --git a/chromium/storage/browser/blob/blob_storage_registry.cc b/chromium/storage/browser/blob/blob_storage_registry.cc index 8ee624f7cec..a0f03b25fd4 100644 --- a/chromium/storage/browser/blob/blob_storage_registry.cc +++ b/chromium/storage/browser/blob/blob_storage_registry.cc @@ -6,6 +6,8 @@ #include <stddef.h> +#include <memory> + #include "base/bind.h" #include "base/callback.h" #include "base/location.h" @@ -37,7 +39,7 @@ GURL ClearBlobUrlRef(const GURL& url) { } // namespace BlobStorageRegistry::Entry::Entry(int refcount, BlobState state) - : refcount(refcount), state(state), exceeded_memory(false) {} + : refcount(refcount), state(state) {} BlobStorageRegistry::Entry::~Entry() {} @@ -58,17 +60,26 @@ BlobStorageRegistry::~BlobStorageRegistry() { } BlobStorageRegistry::Entry* BlobStorageRegistry::CreateEntry( - const std::string& uuid) { + const std::string& uuid, + const std::string& content_type, + const std::string& content_disposition) { DCHECK(!ContainsKey(blob_map_, uuid)); - Entry* entry = new Entry(1, BlobState::RESERVED); - blob_map_.add(uuid, make_scoped_ptr(entry)); - return entry; + std::unique_ptr<Entry> entry(new Entry(1, BlobState::PENDING)); + entry->content_type = content_type; + entry->content_disposition = content_disposition; + Entry* entry_ptr = entry.get(); + blob_map_.add(uuid, std::move(entry)); + return entry_ptr; } bool BlobStorageRegistry::DeleteEntry(const std::string& uuid) { return blob_map_.erase(uuid) == 1; } +bool BlobStorageRegistry::HasEntry(const std::string& uuid) const { + return blob_map_.find(uuid) != blob_map_.end(); +} + BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntry( const std::string& uuid) { BlobMap::iterator found = blob_map_.find(uuid); @@ -77,6 +88,11 @@ BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntry( return found->second; } +const BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntry( + const std::string& uuid) const { + return const_cast<BlobStorageRegistry*>(this)->GetEntry(uuid); +} + bool BlobStorageRegistry::CreateUrlMapping(const GURL& blob_url, const std::string& uuid) { DCHECK(!BlobUrlHasRef(blob_url)); diff --git a/chromium/storage/browser/blob/blob_storage_registry.h b/chromium/storage/browser/blob/blob_storage_registry.h index 54e8b0e0d05..5211094b61a 100644 --- a/chromium/storage/browser/blob/blob_storage_registry.h +++ b/chromium/storage/browser/blob/blob_storage_registry.h @@ -8,6 +8,7 @@ #include <stddef.h> #include <map> +#include <memory> #include <string> #include <vector> @@ -16,6 +17,7 @@ #include "base/macros.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" class GURL; @@ -30,28 +32,37 @@ namespace storage { // uuid. The user must keep track of these. class STORAGE_EXPORT BlobStorageRegistry { public: + // True means the blob was constructed successfully, and false means that + // there was an error, which is reported in the second argument. + using BlobConstructedCallback = + base::Callback<void(bool, IPCBlobCreationCancelCode)>; + enum class BlobState { - // First the renderer reserves the uuid. - RESERVED = 1, - // Second, we are asynchronously transporting data to the browser. - ASYNC_TRANSPORTATION, - // Third, we construct the blob when we have all of the data. - CONSTRUCTION, - // Finally, the blob is built. - ACTIVE + // The blob is pending transportation from the renderer. This is the default + // state on entry construction. + PENDING, + // The blob is complete and can be read from. + COMPLETE, + // The blob is broken and no longer holds data. This happens when there was + // a problem constructing the blob, or we've run out of memory. + BROKEN }; struct STORAGE_EXPORT Entry { size_t refcount; BlobState state; - std::vector<base::Callback<void(bool)>> construction_complete_callbacks; + std::vector<BlobConstructedCallback> build_completion_callbacks; - // Flags - bool exceeded_memory; + // Only applicable if the state == BROKEN. + IPCBlobCreationCancelCode broken_reason = + IPCBlobCreationCancelCode::UNKNOWN; // data and data_builder are mutually exclusive. - scoped_ptr<InternalBlobData> data; - scoped_ptr<InternalBlobData::Builder> data_builder; + std::unique_ptr<InternalBlobData> data; + std::unique_ptr<InternalBlobData::Builder> data_builder; + + std::string content_type; + std::string content_disposition; Entry() = delete; Entry(int refcount, BlobState state); @@ -66,17 +77,22 @@ class STORAGE_EXPORT BlobStorageRegistry { BlobStorageRegistry(); ~BlobStorageRegistry(); - // Creates the blob entry with a refcount of 1 and a state of RESERVED. If + // Creates the blob entry with a refcount of 1 and a state of PENDING. If // the blob is already in use, we return null. - Entry* CreateEntry(const std::string& uuid); + Entry* CreateEntry(const std::string& uuid, + const std::string& content_type, + const std::string& content_disposition); // Removes the blob entry with the given uuid. This does not unmap any // URLs that are pointing to this uuid. Returns if the entry existed. bool DeleteEntry(const std::string& uuid); + bool HasEntry(const std::string& uuid) const; + // Gets the blob entry for the given uuid. Returns nullptr if the entry // does not exist. Entry* GetEntry(const std::string& uuid); + const Entry* GetEntry(const std::string& uuid) const; // Creates a url mapping from blob uuid to the given url. Returns false if // the uuid isn't mapped to an entry or if there already is a map for the URL. @@ -97,7 +113,8 @@ class STORAGE_EXPORT BlobStorageRegistry { size_t url_count() const { return url_to_uuid_.size(); } private: - using BlobMap = base::ScopedPtrHashMap<std::string, scoped_ptr<Entry>>; + friend class ViewBlobInternalsJob; + using BlobMap = base::ScopedPtrHashMap<std::string, std::unique_ptr<Entry>>; using URLMap = std::map<GURL, std::string>; BlobMap blob_map_; diff --git a/chromium/storage/browser/blob/blob_transport_result.h b/chromium/storage/browser/blob/blob_transport_result.h new file mode 100644 index 00000000000..9aa2f72ad4a --- /dev/null +++ b/chromium/storage/browser/blob/blob_transport_result.h @@ -0,0 +1,27 @@ +// Copyright 2015 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. + +#ifndef STORAGE_BROWSER_BLOB_BLOB_TRANSPORT_RESULT_H_ +#define STORAGE_BROWSER_BLOB_BLOB_TRANSPORT_RESULT_H_ + +namespace storage { + +// This 'result' enum is used in the blob transport logic. +enum class BlobTransportResult { + // This means we should flag the incoming IPC as a bad IPC. + BAD_IPC, + // Cancel reasons. + CANCEL_MEMORY_FULL, + CANCEL_FILE_ERROR, + CANCEL_REFERENCED_BLOB_BROKEN, + CANCEL_UNKNOWN, + // This means we're waiting on responses from the renderer. + PENDING_RESPONSES, + // We're done registering or transferring the blob. + DONE +}; + +} // namespace storage + +#endif // STORAGE_BROWSER_BLOB_BLOB_TRANSPORT_RESULT_H_ diff --git a/chromium/storage/browser/blob/blob_url_request_job.cc b/chromium/storage/browser/blob/blob_url_request_job.cc index 783c3866ba5..58863d00355 100644 --- a/chromium/storage/browser/blob/blob_url_request_job.cc +++ b/chromium/storage/browser/blob/blob_url_request_job.cc @@ -177,7 +177,6 @@ void BlobURLRequestJob::DidStart() { NotifyFailure(blob_reader_->net_error()); return; case BlobReader::Status::IO_PENDING: - SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); return; case BlobReader::Status::DONE: DidCalculateSize(net::OK); @@ -188,8 +187,6 @@ void BlobURLRequestJob::DidStart() { void BlobURLRequestJob::DidCalculateSize(int result) { TRACE_EVENT_ASYNC_END1("Blob", "BlobRequest::CountSize", this, "uuid", blob_handle_->uuid()); - // Clear the IO_PENDING status - SetStatus(net::URLRequestStatus()); if (result != net::OK) { NotifyFailure(result); diff --git a/chromium/storage/browser/blob/blob_url_request_job.h b/chromium/storage/browser/blob/blob_url_request_job.h index 70f035684fc..24621f5ac04 100644 --- a/chromium/storage/browser/blob/blob_url_request_job.h +++ b/chromium/storage/browser/blob/blob_url_request_job.h @@ -8,10 +8,10 @@ #include <stddef.h> #include <map> +#include <memory> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "net/http/http_byte_range.h" #include "net/http/http_status_code.h" @@ -73,9 +73,9 @@ class STORAGE_EXPORT BlobURLRequestJob bool byte_range_set_; net::HttpByteRange byte_range_; - scoped_ptr<BlobDataHandle> blob_handle_; - scoped_ptr<BlobReader> blob_reader_; - scoped_ptr<net::HttpResponseInfo> response_info_; + std::unique_ptr<BlobDataHandle> blob_handle_; + std::unique_ptr<BlobReader> blob_reader_; + std::unique_ptr<net::HttpResponseInfo> response_info_; base::WeakPtrFactory<BlobURLRequestJob> weak_factory_; diff --git a/chromium/storage/browser/blob/blob_url_request_job_factory.cc b/chromium/storage/browser/blob/blob_url_request_job_factory.cc index ed9c137af22..1017386eb51 100644 --- a/chromium/storage/browser/blob/blob_url_request_job_factory.cc +++ b/chromium/storage/browser/blob/blob_url_request_job_factory.cc @@ -4,6 +4,7 @@ #include "storage/browser/blob/blob_url_request_job_factory.h" +#include <memory> #include <utility> #include "base/strings/string_util.h" @@ -23,12 +24,12 @@ int kUserDataKey; // The value is not important, the addr is a key. } // namespace // static -scoped_ptr<net::URLRequest> BlobProtocolHandler::CreateBlobRequest( - scoped_ptr<BlobDataHandle> blob_data_handle, +std::unique_ptr<net::URLRequest> BlobProtocolHandler::CreateBlobRequest( + std::unique_ptr<BlobDataHandle> blob_data_handle, const net::URLRequestContext* request_context, net::URLRequest::Delegate* request_delegate) { const GURL kBlobUrl("blob://see_user_data/"); - scoped_ptr<net::URLRequest> request = request_context->CreateRequest( + std::unique_ptr<net::URLRequest> request = request_context->CreateRequest( kBlobUrl, net::DEFAULT_PRIORITY, request_delegate); SetRequestedBlobDataHandle(request.get(), std::move(blob_data_handle)); return request; @@ -37,7 +38,7 @@ scoped_ptr<net::URLRequest> BlobProtocolHandler::CreateBlobRequest( // static void BlobProtocolHandler::SetRequestedBlobDataHandle( net::URLRequest* request, - scoped_ptr<BlobDataHandle> blob_data_handle) { + std::unique_ptr<BlobDataHandle> blob_data_handle) { request->SetUserData(&kUserDataKey, blob_data_handle.release()); } @@ -83,7 +84,7 @@ BlobDataHandle* BlobProtocolHandler::LookupBlobHandle( base::CompareCase::SENSITIVE)) return NULL; std::string uuid = request->url().spec().substr(kPrefix.length()); - scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(uuid); + std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(uuid); BlobDataHandle* handle_ptr = handle.get(); if (handle) { SetRequestedBlobDataHandle(request, std::move(handle)); diff --git a/chromium/storage/browser/blob/blob_url_request_job_factory.h b/chromium/storage/browser/blob/blob_url_request_job_factory.h index 326da9b6f18..f8642ce71af 100644 --- a/chromium/storage/browser/blob/blob_url_request_job_factory.h +++ b/chromium/storage/browser/blob/blob_url_request_job_factory.h @@ -5,10 +5,11 @@ #ifndef STORAGE_BROWSER_BLOB_BLOB_URL_REQUEST_JOB_FACTORY_H_ #define STORAGE_BROWSER_BLOB_BLOB_URL_REQUEST_JOB_FACTORY_H_ +#include <memory> + #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_job_factory.h" #include "storage/browser/storage_browser_export.h" @@ -34,8 +35,8 @@ class STORAGE_EXPORT BlobProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { public: // A helper to manufacture an URLRequest to retrieve the given blob. - static scoped_ptr<net::URLRequest> CreateBlobRequest( - scoped_ptr<BlobDataHandle> blob_data_handle, + static std::unique_ptr<net::URLRequest> CreateBlobRequest( + std::unique_ptr<BlobDataHandle> blob_data_handle, const net::URLRequestContext* request_context, net::URLRequest::Delegate* request_delegate); @@ -43,7 +44,7 @@ class STORAGE_EXPORT BlobProtocolHandler // to SetRequestedBlobDataHandle instead. static void SetRequestedBlobDataHandle( net::URLRequest* request, - scoped_ptr<BlobDataHandle> blob_data_handle); + std::unique_ptr<BlobDataHandle> blob_data_handle); // This gets the handle on the request if it exists. static BlobDataHandle* GetRequestBlobDataHandle(net::URLRequest* request); diff --git a/chromium/storage/browser/blob/internal_blob_data.cc b/chromium/storage/browser/blob/internal_blob_data.cc index cbec2900d69..115c6a65e1f 100644 --- a/chromium/storage/browser/blob/internal_blob_data.cc +++ b/chromium/storage/browser/blob/internal_blob_data.cc @@ -5,6 +5,8 @@ #include "storage/browser/blob/internal_blob_data.h" #include <stddef.h> + +#include <memory> #include <utility> #include "base/containers/hash_tables.h" @@ -32,24 +34,12 @@ void InternalBlobData::Builder::RemoveBlobFromShareableItems( data_->RemoveBlobFromShareableItems(blob_uuid); } -void InternalBlobData::Builder::set_content_type( - const std::string& content_type) { - DCHECK(data_); - data_->content_type_ = content_type; -} - -void InternalBlobData::Builder::set_content_disposition( - const std::string& content_disposition) { - DCHECK(data_); - data_->content_disposition_ = content_disposition; -} - size_t InternalBlobData::Builder::GetNonsharedMemoryUsage() const { DCHECK(data_); return data_->GetUnsharedMemoryUsage(); } -scoped_ptr<InternalBlobData> InternalBlobData::Builder::Build() { +std::unique_ptr<InternalBlobData> InternalBlobData::Builder::Build() { DCHECK(data_); return std::move(data_); } @@ -64,12 +54,6 @@ const std::vector<scoped_refptr<ShareableBlobDataItem>>& InternalBlobData::items() const { return items_; } -const std::string& InternalBlobData::content_type() const { - return content_type_; -} -const std::string& InternalBlobData::content_disposition() const { - return content_disposition_; -} void InternalBlobData::RemoveBlobFromShareableItems( const std::string& blob_uuid) { diff --git a/chromium/storage/browser/blob/internal_blob_data.h b/chromium/storage/browser/blob/internal_blob_data.h index c751762a6a1..65db2f3cdc3 100644 --- a/chromium/storage/browser/blob/internal_blob_data.h +++ b/chromium/storage/browser/blob/internal_blob_data.h @@ -7,6 +7,7 @@ #include <stddef.h> +#include <memory> #include <string> #include <vector> @@ -33,8 +34,6 @@ class InternalBlobData { void RemoveBlobFromShareableItems(const std::string& blob_uuid); const std::vector<scoped_refptr<ShareableBlobDataItem>>& items() const; - const std::string& content_type() const; - const std::string& content_disposition() const; // Gets the memory used by this blob that is not shared by other blobs. This // also doesn't count duplicate items. @@ -60,8 +59,6 @@ class InternalBlobData { ~Builder(); void AppendSharedBlobItem(scoped_refptr<ShareableBlobDataItem> item); - void set_content_type(const std::string& content_type); - void set_content_disposition(const std::string& content_disposition); // Gets the memory used by this builder that is not shared with other blobs. size_t GetNonsharedMemoryUsage() const; @@ -71,10 +68,10 @@ class InternalBlobData { void RemoveBlobFromShareableItems(const std::string& blob_uuid); // The builder is invalid after calling this method. - scoped_ptr<::storage::InternalBlobData> Build(); + std::unique_ptr<::storage::InternalBlobData> Build(); private: - scoped_ptr<::storage::InternalBlobData> data_; + std::unique_ptr<::storage::InternalBlobData> data_; DISALLOW_COPY_AND_ASSIGN(Builder); }; diff --git a/chromium/storage/browser/blob/shareable_blob_data_item.h b/chromium/storage/browser/blob/shareable_blob_data_item.h index 8df83895e40..4c2f9c18332 100644 --- a/chromium/storage/browser/blob/shareable_blob_data_item.h +++ b/chromium/storage/browser/blob/shareable_blob_data_item.h @@ -5,6 +5,8 @@ #ifndef STORAGE_BROWSER_BLOB_SHAREABLE_BLOB_DATA_ITEM_H_ #define STORAGE_BROWSER_BLOB_SHAREABLE_BLOB_DATA_ITEM_H_ +#include <string> + #include "base/containers/hash_tables.h" #include "base/hash.h" #include "base/macros.h" @@ -12,8 +14,8 @@ #include "storage/common/data_element.h" namespace storage { - class BlobDataItem; +class InternalBlobData; // This class allows blob items to be shared between blobs, and is only used by // BlobStorageContext. This class contains both the blob data item and the uuids @@ -34,6 +36,7 @@ class ShareableBlobDataItem : public base::RefCounted<ShareableBlobDataItem> { private: friend class base::RefCounted<ShareableBlobDataItem>; + friend class InternalBlobData; ~ShareableBlobDataItem(); scoped_refptr<BlobDataItem> item_; diff --git a/chromium/storage/browser/blob/upload_blob_element_reader.cc b/chromium/storage/browser/blob/upload_blob_element_reader.cc index 3c86051f92d..95e062836c1 100644 --- a/chromium/storage/browser/blob/upload_blob_element_reader.cc +++ b/chromium/storage/browser/blob/upload_blob_element_reader.cc @@ -5,6 +5,8 @@ #include "storage/browser/blob/upload_blob_element_reader.h" #include <stdint.h> + +#include <memory> #include <utility> #include "base/single_thread_task_runner.h" @@ -16,7 +18,7 @@ namespace storage { UploadBlobElementReader::UploadBlobElementReader( - scoped_ptr<BlobDataHandle> handle, + std::unique_ptr<BlobDataHandle> handle, FileSystemContext* file_system_context, base::SingleThreadTaskRunner* file_task_runner) : handle_(std::move(handle)), diff --git a/chromium/storage/browser/blob/upload_blob_element_reader.h b/chromium/storage/browser/blob/upload_blob_element_reader.h index f8192d0603f..b4802e1510a 100644 --- a/chromium/storage/browser/blob/upload_blob_element_reader.h +++ b/chromium/storage/browser/blob/upload_blob_element_reader.h @@ -7,9 +7,10 @@ #include <stdint.h> +#include <memory> + #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "net/base/completion_callback.h" #include "net/base/upload_element_reader.h" #include "storage/browser/storage_browser_export.h" @@ -33,7 +34,7 @@ class FileSystemContext; class STORAGE_EXPORT UploadBlobElementReader : NON_EXPORTED_BASE(public net::UploadElementReader) { public: - UploadBlobElementReader(scoped_ptr<BlobDataHandle> handle, + UploadBlobElementReader(std::unique_ptr<BlobDataHandle> handle, FileSystemContext* file_system_context, base::SingleThreadTaskRunner* file_task_runner); ~UploadBlobElementReader() override; @@ -53,10 +54,10 @@ class STORAGE_EXPORT UploadBlobElementReader const std::string& uuid() const; private: - scoped_ptr<BlobDataHandle> handle_; + std::unique_ptr<BlobDataHandle> handle_; scoped_refptr<FileSystemContext> file_system_context_; scoped_refptr<base::SingleThreadTaskRunner> file_runner_; - scoped_ptr<BlobReader> reader_; + std::unique_ptr<BlobReader> reader_; DISALLOW_COPY_AND_ASSIGN(UploadBlobElementReader); }; diff --git a/chromium/storage/browser/blob/view_blob_internals_job.cc b/chromium/storage/browser/blob/view_blob_internals_job.cc index cf18d3e4f07..287f9943939 100644 --- a/chromium/storage/browser/blob/view_blob_internals_job.cc +++ b/chromium/storage/browser/blob/view_blob_internals_job.cc @@ -22,7 +22,9 @@ #include "net/base/net_errors.h" #include "net/disk_cache/disk_cache.h" #include "net/url_request/url_request.h" +#include "storage/browser/blob/blob_data_item.h" #include "storage/browser/blob/blob_storage_context.h" +#include "storage/browser/blob/blob_storage_registry.h" #include "storage/browser/blob/internal_blob_data.h" namespace { @@ -140,7 +142,7 @@ int ViewBlobInternalsJob::GetData( data->clear(); StartHTML(data); - if (blob_storage_context_->blob_map_.empty()) + if (blob_storage_context_->registry_.blob_map_.empty()) data->append(kEmptyBlobStorageMessage); else GenerateHTML(data); @@ -149,19 +151,19 @@ int ViewBlobInternalsJob::GetData( } void ViewBlobInternalsJob::GenerateHTML(std::string* out) const { - for (BlobStorageContext::BlobMap::const_iterator iter = - blob_storage_context_->blob_map_.begin(); - iter != blob_storage_context_->blob_map_.end(); - ++iter) { + for (BlobStorageRegistry::BlobMap::const_iterator iter = + blob_storage_context_->registry_.blob_map_.begin(); + iter != blob_storage_context_->registry_.blob_map_.end(); ++iter) { AddHTMLBoldText(iter->first, out); - GenerateHTMLForBlobData(*iter->second->data, iter->second->refcount, out); + GenerateHTMLForBlobData(*iter->second->data, iter->second->content_type, + iter->second->content_disposition, + iter->second->refcount, out); } - if (!blob_storage_context_->public_blob_urls_.empty()) { + if (!blob_storage_context_->registry_.url_to_uuid_.empty()) { AddHorizontalRule(out); - for (BlobStorageContext::BlobURLMap::const_iterator iter = - blob_storage_context_->public_blob_urls_.begin(); - iter != blob_storage_context_->public_blob_urls_.end(); - ++iter) { + for (BlobStorageRegistry::URLMap::const_iterator iter = + blob_storage_context_->registry_.url_to_uuid_.begin(); + iter != blob_storage_context_->registry_.url_to_uuid_.end(); ++iter) { AddHTMLBoldText(iter->first.spec(), out); StartHTMLList(out); AddHTMLListItem(kUUID, iter->second, out); @@ -172,15 +174,17 @@ void ViewBlobInternalsJob::GenerateHTML(std::string* out) const { void ViewBlobInternalsJob::GenerateHTMLForBlobData( const InternalBlobData& blob_data, + const std::string& content_type, + const std::string& content_disposition, int refcount, std::string* out) { StartHTMLList(out); AddHTMLListItem(kRefcount, base::IntToString(refcount), out); - if (!blob_data.content_type().empty()) - AddHTMLListItem(kContentType, blob_data.content_type(), out); - if (!blob_data.content_disposition().empty()) - AddHTMLListItem(kContentDisposition, blob_data.content_disposition(), out); + if (!content_type.empty()) + AddHTMLListItem(kContentType, content_type, out); + if (!content_disposition.empty()) + AddHTMLListItem(kContentDisposition, content_disposition, out); bool has_multi_items = blob_data.items().size() > 1; if (has_multi_items) { diff --git a/chromium/storage/browser/blob/view_blob_internals_job.h b/chromium/storage/browser/blob/view_blob_internals_job.h index 876df990da7..ca6782be333 100644 --- a/chromium/storage/browser/blob/view_blob_internals_job.h +++ b/chromium/storage/browser/blob/view_blob_internals_job.h @@ -43,6 +43,8 @@ class STORAGE_EXPORT ViewBlobInternalsJob void GenerateHTML(std::string* out) const; static void GenerateHTMLForBlobData(const InternalBlobData& blob_data, + const std::string& content_type, + const std::string& content_disposition, int refcount, std::string* out); diff --git a/chromium/storage/browser/database/database_quota_client.cc b/chromium/storage/browser/database/database_quota_client.cc index 66d3dbed1c6..d8ae590231f 100644 --- a/chromium/storage/browser/database/database_quota_client.cc +++ b/chromium/storage/browser/database/database_quota_client.cc @@ -6,16 +6,16 @@ #include <stdint.h> +#include <memory> #include <vector> #include "base/bind.h" #include "base/bind_helpers.h" #include "base/location.h" -#include "base/memory/scoped_ptr.h" #include "base/task_runner_util.h" #include "base/thread_task_runner_handle.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "storage/browser/database/database_tracker.h" #include "storage/browser/database/database_util.h" #include "storage/common/database/database_identifier.h" @@ -133,9 +133,9 @@ void DatabaseQuotaClient::GetOriginUsage(const GURL& origin_url, } base::PostTaskAndReplyWithResult( - db_tracker_thread_.get(), - FROM_HERE, - base::Bind(&GetOriginUsageOnDBThread, db_tracker_, origin_url), + db_tracker_thread_.get(), FROM_HERE, + base::Bind(&GetOriginUsageOnDBThread, base::RetainedRef(db_tracker_), + origin_url), callback); } @@ -154,12 +154,9 @@ void DatabaseQuotaClient::GetOriginsForType( std::set<GURL>* origins_ptr = new std::set<GURL>(); db_tracker_thread_->PostTaskAndReply( FROM_HERE, - base::Bind(&GetOriginsOnDBThread, - db_tracker_, + base::Bind(&GetOriginsOnDBThread, base::RetainedRef(db_tracker_), base::Unretained(origins_ptr)), - base::Bind(&DidGetOrigins, - callback, - base::Owned(origins_ptr))); + base::Bind(&DidGetOrigins, callback, base::Owned(origins_ptr))); } void DatabaseQuotaClient::GetOriginsForHost( @@ -178,13 +175,9 @@ void DatabaseQuotaClient::GetOriginsForHost( std::set<GURL>* origins_ptr = new std::set<GURL>(); db_tracker_thread_->PostTaskAndReply( FROM_HERE, - base::Bind(&GetOriginsForHostOnDBThread, - db_tracker_, - base::Unretained(origins_ptr), - host), - base::Bind(&DidGetOrigins, - callback, - base::Owned(origins_ptr))); + base::Bind(&GetOriginsForHostOnDBThread, base::RetainedRef(db_tracker_), + base::Unretained(origins_ptr), host), + base::Bind(&DidGetOrigins, callback, base::Owned(origins_ptr))); } void DatabaseQuotaClient::DeleteOriginData(const GURL& origin, @@ -199,10 +192,9 @@ void DatabaseQuotaClient::DeleteOriginData(const GURL& origin, return; } - base::Callback<void(int)> delete_callback = - base::Bind(&DidDeleteOriginData, - base::ThreadTaskRunnerHandle::Get(), - callback); + base::Callback<void(int)> delete_callback = base::Bind( + &DidDeleteOriginData, + base::RetainedRef(base::ThreadTaskRunnerHandle::Get()), callback); PostTaskAndReplyWithResult( db_tracker_thread_.get(), diff --git a/chromium/storage/browser/database/database_tracker.h b/chromium/storage/browser/database/database_tracker.h index 4b7158e8c44..823e1da61a9 100644 --- a/chromium/storage/browser/database/database_tracker.h +++ b/chromium/storage/browser/database/database_tracker.h @@ -8,6 +8,7 @@ #include <stdint.h> #include <map> +#include <memory> #include <set> #include <utility> @@ -15,7 +16,6 @@ #include "base/files/file_path.h" #include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/observer_list.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" @@ -282,9 +282,9 @@ class STORAGE_EXPORT DatabaseTracker bool shutting_down_; const base::FilePath profile_path_; const base::FilePath db_dir_; - scoped_ptr<sql::Connection> db_; - scoped_ptr<DatabasesTable> databases_table_; - scoped_ptr<sql::MetaTable> meta_table_; + std::unique_ptr<sql::Connection> db_; + std::unique_ptr<DatabasesTable> databases_table_; + std::unique_ptr<sql::MetaTable> meta_table_; base::ObserverList<Observer, true> observers_; std::map<std::string, CachedOriginInfo> origins_info_map_; DatabaseConnections database_connections_; diff --git a/chromium/storage/browser/database/database_util.cc b/chromium/storage/browser/database/database_util.cc index 77e3888a9be..c9d232494f9 100644 --- a/chromium/storage/browser/database/database_util.cc +++ b/chromium/storage/browser/database/database_util.cc @@ -101,9 +101,4 @@ base::FilePath DatabaseUtil::GetFullFilePathForVfsFile( return full_path; } -bool DatabaseUtil::IsValidOriginIdentifier( - const std::string& origin_identifier) { - return GetOriginFromIdentifier(origin_identifier).is_valid(); -} - } // namespace storage diff --git a/chromium/storage/browser/database/database_util.h b/chromium/storage/browser/database/database_util.h index 6c67fac930d..cf106594b62 100644 --- a/chromium/storage/browser/database/database_util.h +++ b/chromium/storage/browser/database/database_util.h @@ -31,7 +31,6 @@ class STORAGE_EXPORT DatabaseUtil { static base::FilePath GetFullFilePathForVfsFile( DatabaseTracker* db_tracker, const base::string16& vfs_file_name); - static bool IsValidOriginIdentifier(const std::string& origin_identifier); }; } // namespace storage diff --git a/chromium/storage/browser/database/databases_table.cc b/chromium/storage/browser/database/databases_table.cc index a1bc479464c..d00b21836d6 100644 --- a/chromium/storage/browser/database/databases_table.cc +++ b/chromium/storage/browser/database/databases_table.cc @@ -14,6 +14,8 @@ namespace storage { DatabaseDetails::DatabaseDetails() : estimated_size(0) { } +DatabaseDetails::DatabaseDetails(const DatabaseDetails& other) = default; + DatabaseDetails::~DatabaseDetails() {} bool DatabasesTable::Init() { diff --git a/chromium/storage/browser/database/databases_table.h b/chromium/storage/browser/database/databases_table.h index 78e18ba2351..6dce97c7a47 100644 --- a/chromium/storage/browser/database/databases_table.h +++ b/chromium/storage/browser/database/databases_table.h @@ -20,6 +20,7 @@ namespace storage { struct STORAGE_EXPORT DatabaseDetails { DatabaseDetails(); + DatabaseDetails(const DatabaseDetails& other); ~DatabaseDetails(); std::string origin_identifier; diff --git a/chromium/storage/browser/fileapi/async_file_util.h b/chromium/storage/browser/fileapi/async_file_util.h index a36114c8b1f..b689e294126 100644 --- a/chromium/storage/browser/fileapi/async_file_util.h +++ b/chromium/storage/browser/fileapi/async_file_util.h @@ -7,13 +7,13 @@ #include <stdint.h> +#include <memory> #include <vector> #include "base/callback_forward.h" #include "base/files/file.h" #include "base/files/file_util_proxy.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/fileapi/file_system_operation.h" #include "storage/browser/storage_browser_export.h" #include "storage/common/fileapi/directory_entry.h" @@ -101,11 +101,10 @@ class AsyncFileUtil { // FileSystemOperationImpl::OpenFile calls this. // This is used only by Pepper/NaCl File API. // - virtual void CreateOrOpen( - scoped_ptr<FileSystemOperationContext> context, - const FileSystemURL& url, - int file_flags, - const CreateOrOpenCallback& callback) = 0; + virtual void CreateOrOpen(std::unique_ptr<FileSystemOperationContext> context, + const FileSystemURL& url, + int file_flags, + const CreateOrOpenCallback& callback) = 0; // Ensures that the given |url| exist. This creates a empty new file // at |url| if the |url| does not exist. @@ -120,7 +119,7 @@ class AsyncFileUtil { // and there was an error while creating a new file. // virtual void EnsureFileExists( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const EnsureFileExistsCallback& callback) = 0; @@ -138,7 +137,7 @@ class AsyncFileUtil { // - Other error code if it failed to create a directory. // virtual void CreateDirectory( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, bool exclusive, bool recursive, @@ -152,7 +151,7 @@ class AsyncFileUtil { // - File::FILE_ERROR_NOT_FOUND if the file doesn't exist. // - Other error code if there was an error while retrieving the file info. // - virtual void GetFileInfo(scoped_ptr<FileSystemOperationContext> context, + virtual void GetFileInfo(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, int fields, const GetFileInfoCallback& callback) = 0; @@ -176,7 +175,7 @@ class AsyncFileUtil { // is a file (not a directory). // virtual void ReadDirectory( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const ReadDirectoryCallback& callback) = 0; @@ -187,12 +186,11 @@ class AsyncFileUtil { // FileSystemOperationImpl::TouchFile calls this. // This is used only by Pepper/NaCl File API. // - virtual void Touch( - scoped_ptr<FileSystemOperationContext> context, - const FileSystemURL& url, - const base::Time& last_access_time, - const base::Time& last_modified_time, - const StatusCallback& callback) = 0; + virtual void Touch(std::unique_ptr<FileSystemOperationContext> context, + const FileSystemURL& url, + const base::Time& last_access_time, + const base::Time& last_modified_time, + const StatusCallback& callback) = 0; // Truncates a file at |path| to |length|. If |length| is larger than // the original file size, the file will be extended, and the extended @@ -203,7 +201,7 @@ class AsyncFileUtil { // This reports following error code via |callback|: // - File::FILE_ERROR_NOT_FOUND if the file doesn't exist. // - virtual void Truncate(scoped_ptr<FileSystemOperationContext> context, + virtual void Truncate(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, int64_t length, const StatusCallback& callback) = 0; @@ -230,7 +228,7 @@ class AsyncFileUtil { // its parent path is a file. // virtual void CopyFileLocal( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& src_url, const FileSystemURL& dest_url, CopyOrMoveOption option, @@ -253,7 +251,7 @@ class AsyncFileUtil { // its parent path is a file. // virtual void MoveFileLocal( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& src_url, const FileSystemURL& dest_url, CopyOrMoveOption option, @@ -273,10 +271,10 @@ class AsyncFileUtil { // its parent path is a file. // virtual void CopyInForeignFile( - scoped_ptr<FileSystemOperationContext> context, - const base::FilePath& src_file_path, - const FileSystemURL& dest_url, - const StatusCallback& callback) = 0; + std::unique_ptr<FileSystemOperationContext> context, + const base::FilePath& src_file_path, + const FileSystemURL& dest_url, + const StatusCallback& callback) = 0; // Deletes a single file. // @@ -286,10 +284,9 @@ class AsyncFileUtil { // - File::FILE_ERROR_NOT_FOUND if |url| does not exist. // - File::FILE_ERROR_NOT_A_FILE if |url| is not a file. // - virtual void DeleteFile( - scoped_ptr<FileSystemOperationContext> context, - const FileSystemURL& url, - const StatusCallback& callback) = 0; + virtual void DeleteFile(std::unique_ptr<FileSystemOperationContext> context, + const FileSystemURL& url, + const StatusCallback& callback) = 0; // Removes a single empty directory. // @@ -301,7 +298,7 @@ class AsyncFileUtil { // - File::FILE_ERROR_NOT_EMPTY if |url| is not empty. // virtual void DeleteDirectory( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const StatusCallback& callback) = 0; @@ -319,7 +316,7 @@ class AsyncFileUtil { // - File::FILE_ERROR_NOT_FOUND if |url| does not exist. // - File::FILE_ERROR_INVALID_OPERATION if this operation is not supported. virtual void DeleteRecursively( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const StatusCallback& callback) = 0; @@ -355,7 +352,7 @@ class AsyncFileUtil { // dependent) in error cases, and the caller should always // check the return code. virtual void CreateSnapshotFile( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const CreateSnapshotFileCallback& callback) = 0; diff --git a/chromium/storage/browser/fileapi/async_file_util_adapter.cc b/chromium/storage/browser/fileapi/async_file_util_adapter.cc index 361c73a7f09..8797ab7f5e8 100644 --- a/chromium/storage/browser/fileapi/async_file_util_adapter.cc +++ b/chromium/storage/browser/fileapi/async_file_util_adapter.cc @@ -6,6 +6,8 @@ #include <stddef.h> #include <stdint.h> + +#include <memory> #include <utility> #include <vector> @@ -112,7 +114,7 @@ void ReadDirectoryHelper(FileSystemFileUtil* file_util, // assuming that they are reading much more entries than this constant.) const size_t kResultChunkSize = 100; - scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( + std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( file_util->CreateFileEnumerator(context, url)); base::FilePath current; @@ -153,7 +155,7 @@ AsyncFileUtilAdapter::~AsyncFileUtilAdapter() { } void AsyncFileUtilAdapter::CreateOrOpen( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, int file_flags, const CreateOrOpenCallback& callback) { @@ -167,7 +169,7 @@ void AsyncFileUtilAdapter::CreateOrOpen( } void AsyncFileUtilAdapter::EnsureFileExists( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const EnsureFileExistsCallback& callback) { EnsureFileExistsHelper* helper = new EnsureFileExistsHelper; @@ -181,7 +183,7 @@ void AsyncFileUtilAdapter::EnsureFileExists( } void AsyncFileUtilAdapter::CreateDirectory( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, bool exclusive, bool recursive, @@ -197,7 +199,7 @@ void AsyncFileUtilAdapter::CreateDirectory( } void AsyncFileUtilAdapter::GetFileInfo( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, int /* fields */, const GetFileInfoCallback& callback) { @@ -212,20 +214,20 @@ void AsyncFileUtilAdapter::GetFileInfo( } void AsyncFileUtilAdapter::ReadDirectory( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const ReadDirectoryCallback& callback) { FileSystemOperationContext* context_ptr = context.release(); const bool success = context_ptr->task_runner()->PostTask( FROM_HERE, - Bind(&ReadDirectoryHelper, - sync_file_util_.get(), base::Owned(context_ptr), url, - base::ThreadTaskRunnerHandle::Get(), callback)); + Bind(&ReadDirectoryHelper, sync_file_util_.get(), + base::Owned(context_ptr), url, + base::RetainedRef(base::ThreadTaskRunnerHandle::Get()), callback)); DCHECK(success); } void AsyncFileUtilAdapter::Touch( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const base::Time& last_access_time, const base::Time& last_modified_time, @@ -241,7 +243,7 @@ void AsyncFileUtilAdapter::Touch( } void AsyncFileUtilAdapter::Truncate( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, int64_t length, const StatusCallback& callback) { @@ -255,7 +257,7 @@ void AsyncFileUtilAdapter::Truncate( } void AsyncFileUtilAdapter::CopyFileLocal( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& src_url, const FileSystemURL& dest_url, CopyOrMoveOption option, @@ -273,7 +275,7 @@ void AsyncFileUtilAdapter::CopyFileLocal( } void AsyncFileUtilAdapter::MoveFileLocal( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& src_url, const FileSystemURL& dest_url, CopyOrMoveOption option, @@ -289,10 +291,10 @@ void AsyncFileUtilAdapter::MoveFileLocal( } void AsyncFileUtilAdapter::CopyInForeignFile( - scoped_ptr<FileSystemOperationContext> context, - const base::FilePath& src_file_path, - const FileSystemURL& dest_url, - const StatusCallback& callback) { + std::unique_ptr<FileSystemOperationContext> context, + const base::FilePath& src_file_path, + const FileSystemURL& dest_url, + const StatusCallback& callback) { FileSystemOperationContext* context_ptr = context.release(); const bool success = base::PostTaskAndReplyWithResult( context_ptr->task_runner(), FROM_HERE, @@ -304,7 +306,7 @@ void AsyncFileUtilAdapter::CopyInForeignFile( } void AsyncFileUtilAdapter::DeleteFile( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const StatusCallback& callback) { FileSystemOperationContext* context_ptr = context.release(); @@ -318,7 +320,7 @@ void AsyncFileUtilAdapter::DeleteFile( } void AsyncFileUtilAdapter::DeleteDirectory( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const StatusCallback& callback) { FileSystemOperationContext* context_ptr = context.release(); @@ -332,14 +334,14 @@ void AsyncFileUtilAdapter::DeleteDirectory( } void AsyncFileUtilAdapter::DeleteRecursively( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const StatusCallback& callback) { callback.Run(base::File::FILE_ERROR_INVALID_OPERATION); } void AsyncFileUtilAdapter::CreateSnapshotFile( - scoped_ptr<FileSystemOperationContext> context, + std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const CreateSnapshotFileCallback& callback) { FileSystemOperationContext* context_ptr = context.release(); diff --git a/chromium/storage/browser/fileapi/async_file_util_adapter.h b/chromium/storage/browser/fileapi/async_file_util_adapter.h index 5cbf829c71b..4777d92f5a6 100644 --- a/chromium/storage/browser/fileapi/async_file_util_adapter.h +++ b/chromium/storage/browser/fileapi/async_file_util_adapter.h @@ -7,8 +7,10 @@ #include <stdint.h> +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "storage/browser/fileapi/async_file_util.h" namespace storage { @@ -29,8 +31,8 @@ class STORAGE_EXPORT AsyncFileUtilAdapter : public NON_EXPORTED_BASE(AsyncFileUtil) { public: // Creates a new AsyncFileUtil for |sync_file_util|. This takes the - // ownership of |sync_file_util|. (This doesn't take scoped_ptr<> just - // to save extra make_scoped_ptr; in all use cases a new fresh FileUtil is + // ownership of |sync_file_util|. (This doesn't take std::unique_ptr<> just + // to save extra base::WrapUnique; in all use cases a new fresh FileUtil is // created only for this adapter.) explicit AsyncFileUtilAdapter(FileSystemFileUtil* sync_file_util); @@ -41,64 +43,64 @@ class STORAGE_EXPORT AsyncFileUtilAdapter } // AsyncFileUtil overrides. - void CreateOrOpen(scoped_ptr<FileSystemOperationContext> context, + void CreateOrOpen(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, int file_flags, const CreateOrOpenCallback& callback) override; - void EnsureFileExists(scoped_ptr<FileSystemOperationContext> context, + void EnsureFileExists(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const EnsureFileExistsCallback& callback) override; - void CreateDirectory(scoped_ptr<FileSystemOperationContext> context, + void CreateDirectory(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, bool exclusive, bool recursive, const StatusCallback& callback) override; - void GetFileInfo(scoped_ptr<FileSystemOperationContext> context, + void GetFileInfo(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, int /* fields */, const GetFileInfoCallback& callback) override; - void ReadDirectory(scoped_ptr<FileSystemOperationContext> context, + void ReadDirectory(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const ReadDirectoryCallback& callback) override; - void Touch(scoped_ptr<FileSystemOperationContext> context, + void Touch(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const base::Time& last_access_time, const base::Time& last_modified_time, const StatusCallback& callback) override; - void Truncate(scoped_ptr<FileSystemOperationContext> context, + void Truncate(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, int64_t length, const StatusCallback& callback) override; - void CopyFileLocal(scoped_ptr<FileSystemOperationContext> context, + void CopyFileLocal(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& src_url, const FileSystemURL& dest_url, CopyOrMoveOption option, const CopyFileProgressCallback& progress_callback, const StatusCallback& callback) override; - void MoveFileLocal(scoped_ptr<FileSystemOperationContext> context, + void MoveFileLocal(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& src_url, const FileSystemURL& dest_url, CopyOrMoveOption option, const StatusCallback& callback) override; - void CopyInForeignFile(scoped_ptr<FileSystemOperationContext> context, + void CopyInForeignFile(std::unique_ptr<FileSystemOperationContext> context, const base::FilePath& src_file_path, const FileSystemURL& dest_url, const StatusCallback& callback) override; - void DeleteFile(scoped_ptr<FileSystemOperationContext> context, + void DeleteFile(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const StatusCallback& callback) override; - void DeleteDirectory(scoped_ptr<FileSystemOperationContext> context, + void DeleteDirectory(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const StatusCallback& callback) override; - void DeleteRecursively(scoped_ptr<FileSystemOperationContext> context, + void DeleteRecursively(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const StatusCallback& callback) override; - void CreateSnapshotFile(scoped_ptr<FileSystemOperationContext> context, + void CreateSnapshotFile(std::unique_ptr<FileSystemOperationContext> context, const FileSystemURL& url, const CreateSnapshotFileCallback& callback) override; private: - scoped_ptr<FileSystemFileUtil> sync_file_util_; + std::unique_ptr<FileSystemFileUtil> sync_file_util_; DISALLOW_COPY_AND_ASSIGN(AsyncFileUtilAdapter); }; diff --git a/chromium/storage/browser/fileapi/copy_or_move_operation_delegate.cc b/chromium/storage/browser/fileapi/copy_or_move_operation_delegate.cc index 15772785292..ca5b409e127 100644 --- a/chromium/storage/browser/fileapi/copy_or_move_operation_delegate.cc +++ b/chromium/storage/browser/fileapi/copy_or_move_operation_delegate.cc @@ -5,6 +5,9 @@ #include "storage/browser/fileapi/copy_or_move_operation_delegate.h" #include <stdint.h> + +#include <memory> +#include <tuple> #include <utility> #include "base/bind.h" @@ -346,7 +349,7 @@ class SnapshotCopyOrMoveImpl CopyOrMoveOperationDelegate::CopyOrMoveOption option_; CopyOrMoveFileValidatorFactory* validator_factory_; - scoped_ptr<CopyOrMoveFileValidator> validator_; + std::unique_ptr<CopyOrMoveFileValidator> validator_; FileSystemOperation::CopyFileProgressCallback file_progress_callback_; bool cancel_requested_; base::WeakPtrFactory<SnapshotCopyOrMoveImpl> weak_factory_; @@ -373,8 +376,8 @@ class StreamCopyOrMoveImpl const FileSystemURL& src_url, const FileSystemURL& dest_url, CopyOrMoveOperationDelegate::CopyOrMoveOption option, - scoped_ptr<storage::FileStreamReader> reader, - scoped_ptr<FileStreamWriter> writer, + std::unique_ptr<storage::FileStreamReader> reader, + std::unique_ptr<FileStreamWriter> writer, const FileSystemOperation::CopyFileProgressCallback& file_progress_callback) : operation_runner_(operation_runner), @@ -411,21 +414,21 @@ class StreamCopyOrMoveImpl void NotifyOnStartUpdate(const FileSystemURL& url) { if (file_system_context_->GetUpdateObservers(url.type())) { file_system_context_->GetUpdateObservers(url.type()) - ->Notify(&FileUpdateObserver::OnStartUpdate, base::MakeTuple(url)); + ->Notify(&FileUpdateObserver::OnStartUpdate, std::make_tuple(url)); } } void NotifyOnModifyFile(const FileSystemURL& url) { if (file_system_context_->GetChangeObservers(url.type())) { file_system_context_->GetChangeObservers(url.type()) - ->Notify(&FileChangeObserver::OnModifyFile, base::MakeTuple(url)); + ->Notify(&FileChangeObserver::OnModifyFile, std::make_tuple(url)); } } void NotifyOnEndUpdate(const FileSystemURL& url) { if (file_system_context_->GetUpdateObservers(url.type())) { file_system_context_->GetUpdateObservers(url.type()) - ->Notify(&FileUpdateObserver::OnEndUpdate, base::MakeTuple(url)); + ->Notify(&FileUpdateObserver::OnEndUpdate, std::make_tuple(url)); } } @@ -577,10 +580,10 @@ class StreamCopyOrMoveImpl FileSystemURL src_url_; FileSystemURL dest_url_; CopyOrMoveOperationDelegate::CopyOrMoveOption option_; - scoped_ptr<storage::FileStreamReader> reader_; - scoped_ptr<FileStreamWriter> writer_; + std::unique_ptr<storage::FileStreamReader> reader_; + std::unique_ptr<FileStreamWriter> writer_; FileSystemOperation::CopyFileProgressCallback file_progress_callback_; - scoped_ptr<CopyOrMoveOperationDelegate::StreamCopyHelper> copy_helper_; + std::unique_ptr<CopyOrMoveOperationDelegate::StreamCopyHelper> copy_helper_; bool cancel_requested_; base::WeakPtrFactory<StreamCopyOrMoveImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(StreamCopyOrMoveImpl); @@ -589,8 +592,8 @@ class StreamCopyOrMoveImpl } // namespace CopyOrMoveOperationDelegate::StreamCopyHelper::StreamCopyHelper( - scoped_ptr<storage::FileStreamReader> reader, - scoped_ptr<FileStreamWriter> writer, + std::unique_ptr<storage::FileStreamReader> reader, + std::unique_ptr<FileStreamWriter> writer, storage::FlushPolicy flush_policy, int buffer_size, const FileSystemOperation::CopyFileProgressCallback& file_progress_callback, @@ -818,10 +821,10 @@ void CopyOrMoveOperationDelegate::ProcessFile( } if (!validator_factory) { - scoped_ptr<storage::FileStreamReader> reader = + std::unique_ptr<storage::FileStreamReader> reader = file_system_context()->CreateFileStreamReader( src_url, 0 /* offset */, storage::kMaximumLength, base::Time()); - scoped_ptr<FileStreamWriter> writer = + std::unique_ptr<FileStreamWriter> writer = file_system_context()->CreateFileStreamWriter(dest_url, 0); if (reader && writer) { impl = new StreamCopyOrMoveImpl( diff --git a/chromium/storage/browser/fileapi/copy_or_move_operation_delegate.h b/chromium/storage/browser/fileapi/copy_or_move_operation_delegate.h index c3ff20a2bfc..a853b781124 100644 --- a/chromium/storage/browser/fileapi/copy_or_move_operation_delegate.h +++ b/chromium/storage/browser/fileapi/copy_or_move_operation_delegate.h @@ -7,12 +7,12 @@ #include <stdint.h> +#include <memory> #include <set> #include <stack> #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "storage/browser/fileapi/recursive_operation_delegate.h" @@ -51,8 +51,8 @@ class CopyOrMoveOperationDelegate class STORAGE_EXPORT StreamCopyHelper { public: StreamCopyHelper( - scoped_ptr<storage::FileStreamReader> reader, - scoped_ptr<FileStreamWriter> writer, + std::unique_ptr<storage::FileStreamReader> reader, + std::unique_ptr<FileStreamWriter> writer, FlushPolicy flush_policy, int buffer_size, const FileSystemOperation::CopyFileProgressCallback& @@ -81,8 +81,8 @@ class CopyOrMoveOperationDelegate void Flush(const StatusCallback& callback, bool is_eof); void DidFlush(const StatusCallback& callback, bool is_eof, int result); - scoped_ptr<storage::FileStreamReader> reader_; - scoped_ptr<FileStreamWriter> writer_; + std::unique_ptr<storage::FileStreamReader> reader_; + std::unique_ptr<FileStreamWriter> writer_; const FlushPolicy flush_policy_; FileSystemOperation::CopyFileProgressCallback file_progress_callback_; scoped_refptr<net::IOBufferWithSize> io_buffer_; diff --git a/chromium/storage/browser/fileapi/dragged_file_util.cc b/chromium/storage/browser/fileapi/dragged_file_util.cc index dc6db41c120..1eaac6a3fdf 100644 --- a/chromium/storage/browser/fileapi/dragged_file_util.cc +++ b/chromium/storage/browser/fileapi/dragged_file_util.cc @@ -6,6 +6,7 @@ #include <stdint.h> +#include <memory> #include <string> #include <vector> @@ -87,10 +88,9 @@ base::File::Error DraggedFileUtil::GetFileInfo( return error; } -scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> - DraggedFileUtil::CreateFileEnumerator( - FileSystemOperationContext* context, - const FileSystemURL& root) { +std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> +DraggedFileUtil::CreateFileEnumerator(FileSystemOperationContext* context, + const FileSystemURL& root) { DCHECK(root.is_valid()); if (!root.path().empty()) return LocalFileUtil::CreateFileEnumerator(context, root); @@ -99,7 +99,8 @@ scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> std::vector<FileInfo> toplevels; IsolatedContext::GetInstance()->GetDraggedFileInfo( root.filesystem_id(), &toplevels); - return scoped_ptr<AbstractFileEnumerator>(new SetFileEnumerator(toplevels)); + return std::unique_ptr<AbstractFileEnumerator>( + new SetFileEnumerator(toplevels)); } } // namespace storage diff --git a/chromium/storage/browser/fileapi/dragged_file_util.h b/chromium/storage/browser/fileapi/dragged_file_util.h index adf47d39482..c170910cafd 100644 --- a/chromium/storage/browser/fileapi/dragged_file_util.h +++ b/chromium/storage/browser/fileapi/dragged_file_util.h @@ -5,8 +5,9 @@ #ifndef STORAGE_BROWSER_FILEAPI_DRAGGED_FILE_UTIL_H_ #define STORAGE_BROWSER_FILEAPI_DRAGGED_FILE_UTIL_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/fileapi/local_file_util.h" #include "storage/browser/storage_browser_export.h" @@ -27,7 +28,7 @@ class STORAGE_EXPORT DraggedFileUtil : public LocalFileUtil { const FileSystemURL& url, base::File::Info* file_info, base::FilePath* platform_path) override; - scoped_ptr<AbstractFileEnumerator> CreateFileEnumerator( + std::unique_ptr<AbstractFileEnumerator> CreateFileEnumerator( FileSystemOperationContext* context, const FileSystemURL& root_url) override; diff --git a/chromium/storage/browser/fileapi/external_mount_points.cc b/chromium/storage/browser/fileapi/external_mount_points.cc index 9fdb4f9c1f9..f9ffdbdbb99 100644 --- a/chromium/storage/browser/fileapi/external_mount_points.cc +++ b/chromium/storage/browser/fileapi/external_mount_points.cc @@ -24,7 +24,7 @@ base::FilePath NormalizeFilePath(const base::FilePath& path) { return path; base::FilePath::StringType path_str = path.StripTrailingSeparators().value(); - if (!base::FilePath::IsSeparator(path_str[path_str.length() - 1])) + if (!base::FilePath::IsSeparator(path_str.back())) path_str.append(FILE_PATH_LITERAL("/")); return base::FilePath(path_str).NormalizePathSeparators(); diff --git a/chromium/storage/browser/fileapi/file_system_backend.h b/chromium/storage/browser/fileapi/file_system_backend.h index 0c06b1c04d7..c17c8895ebc 100644 --- a/chromium/storage/browser/fileapi/file_system_backend.h +++ b/chromium/storage/browser/fileapi/file_system_backend.h @@ -8,13 +8,13 @@ #include <stdint.h> #include <limits> +#include <memory> #include <string> #include <vector> #include "base/callback_forward.h" #include "base/files/file.h" #include "base/files/file_path.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/fileapi/file_permission_policy.h" #include "storage/browser/fileapi/open_file_system_mode.h" #include "storage/browser/fileapi/task_runner_bound_observer_list.h" @@ -119,7 +119,7 @@ class STORAGE_EXPORT FileSystemBackend { // This method itself does *not* check if the given path exists and is a // regular file. At most |max_bytes_to_read| can be fetched from the file // stream reader. - virtual scoped_ptr<storage::FileStreamReader> CreateFileStreamReader( + virtual std::unique_ptr<storage::FileStreamReader> CreateFileStreamReader( const FileSystemURL& url, int64_t offset, int64_t max_bytes_to_read, @@ -130,7 +130,7 @@ class STORAGE_EXPORT FileSystemBackend { // offset |offset|. // This method itself does *not* check if the given path exists and is a // regular file. - virtual scoped_ptr<FileStreamWriter> CreateFileStreamWriter( + virtual std::unique_ptr<FileStreamWriter> CreateFileStreamWriter( const FileSystemURL& url, int64_t offset, FileSystemContext* context) const = 0; diff --git a/chromium/storage/browser/fileapi/file_system_context.cc b/chromium/storage/browser/fileapi/file_system_context.cc index 6d84f1ed05d..94f5ab2b18c 100644 --- a/chromium/storage/browser/fileapi/file_system_context.cc +++ b/chromium/storage/browser/fileapi/file_system_context.cc @@ -6,10 +6,13 @@ #include <stddef.h> #include <stdint.h> + +#include <memory> #include <utility> #include "base/bind.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" #include "base/task_runner_util.h" @@ -104,7 +107,6 @@ int FileSystemContext::GetPermissionPolicy(FileSystemType type) { FILE_PERMISSION_USE_FILE_PERMISSION; case kFileSystemTypeDeviceMedia: - case kFileSystemTypeIphoto: case kFileSystemTypeItunes: case kFileSystemTypeNativeMedia: case kFileSystemTypePicasa: @@ -429,46 +431,44 @@ void FileSystemContext::DeleteFileSystem( } base::PostTaskAndReplyWithResult( - default_file_task_runner(), - FROM_HERE, + default_file_task_runner(), FROM_HERE, // It is safe to pass Unretained(quota_util) since context owns it. base::Bind(&FileSystemQuotaUtil::DeleteOriginDataOnFileTaskRunner, base::Unretained(backend->GetQuotaUtil()), - make_scoped_refptr(this), - base::Unretained(quota_manager_proxy()), - origin_url, - type), + base::RetainedRef(this), + base::Unretained(quota_manager_proxy()), origin_url, type), callback); } -scoped_ptr<storage::FileStreamReader> FileSystemContext::CreateFileStreamReader( +std::unique_ptr<storage::FileStreamReader> +FileSystemContext::CreateFileStreamReader( const FileSystemURL& url, int64_t offset, int64_t max_bytes_to_read, const base::Time& expected_modification_time) { if (!url.is_valid()) - return scoped_ptr<storage::FileStreamReader>(); + return std::unique_ptr<storage::FileStreamReader>(); FileSystemBackend* backend = GetFileSystemBackend(url.type()); if (!backend) - return scoped_ptr<storage::FileStreamReader>(); + return std::unique_ptr<storage::FileStreamReader>(); return backend->CreateFileStreamReader( url, offset, max_bytes_to_read, expected_modification_time, this); } -scoped_ptr<FileStreamWriter> FileSystemContext::CreateFileStreamWriter( +std::unique_ptr<FileStreamWriter> FileSystemContext::CreateFileStreamWriter( const FileSystemURL& url, int64_t offset) { if (!url.is_valid()) - return scoped_ptr<FileStreamWriter>(); + return std::unique_ptr<FileStreamWriter>(); FileSystemBackend* backend = GetFileSystemBackend(url.type()); if (!backend) - return scoped_ptr<FileStreamWriter>(); + return std::unique_ptr<FileStreamWriter>(); return backend->CreateFileStreamWriter(url, offset, this); } -scoped_ptr<FileSystemOperationRunner> +std::unique_ptr<FileSystemOperationRunner> FileSystemContext::CreateFileSystemOperationRunner() { - return make_scoped_ptr(new FileSystemOperationRunner(this)); + return base::WrapUnique(new FileSystemOperationRunner(this)); } FileSystemURL FileSystemContext::CrackURL(const GURL& url) const { diff --git a/chromium/storage/browser/fileapi/file_system_context.h b/chromium/storage/browser/fileapi/file_system_context.h index c504a0f91ff..d5d4e865802 100644 --- a/chromium/storage/browser/fileapi/file_system_context.h +++ b/chromium/storage/browser/fileapi/file_system_context.h @@ -8,6 +8,7 @@ #include <stdint.h> #include <map> +#include <memory> #include <string> #include <vector> @@ -15,7 +16,6 @@ #include "base/files/file.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "base/sequenced_task_runner_helpers.h" #include "storage/browser/fileapi/file_system_url.h" @@ -256,7 +256,7 @@ class STORAGE_EXPORT FileSystemContext // The resolved FileSystemBackend could perform further specialization // depending on the filesystem type pointed by the |url|. // At most |max_bytes_to_read| can be fetched from the file stream reader. - scoped_ptr<storage::FileStreamReader> CreateFileStreamReader( + std::unique_ptr<storage::FileStreamReader> CreateFileStreamReader( const FileSystemURL& url, int64_t offset, int64_t max_bytes_to_read, @@ -264,11 +264,12 @@ class STORAGE_EXPORT FileSystemContext // Creates new FileStreamWriter instance to write into a file pointed by // |url| from |offset|. - scoped_ptr<FileStreamWriter> CreateFileStreamWriter(const FileSystemURL& url, - int64_t offset); + std::unique_ptr<FileStreamWriter> CreateFileStreamWriter( + const FileSystemURL& url, + int64_t offset); // Creates a new FileSystemOperationRunner. - scoped_ptr<FileSystemOperationRunner> CreateFileSystemOperationRunner(); + std::unique_ptr<FileSystemOperationRunner> CreateFileSystemOperationRunner(); base::SequencedTaskRunner* default_file_task_runner() { return default_file_task_runner_.get(); @@ -379,14 +380,14 @@ class STORAGE_EXPORT FileSystemContext scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_; - scoped_ptr<SandboxFileSystemBackendDelegate> sandbox_delegate_; + std::unique_ptr<SandboxFileSystemBackendDelegate> sandbox_delegate_; // Regular file system backends. - scoped_ptr<SandboxFileSystemBackend> sandbox_backend_; - scoped_ptr<IsolatedFileSystemBackend> isolated_backend_; + std::unique_ptr<SandboxFileSystemBackend> sandbox_backend_; + std::unique_ptr<IsolatedFileSystemBackend> isolated_backend_; // Additional file system backends. - scoped_ptr<PluginPrivateFileSystemBackend> plugin_private_backend_; + std::unique_ptr<PluginPrivateFileSystemBackend> plugin_private_backend_; ScopedVector<FileSystemBackend> additional_backends_; std::vector<URLRequestAutoMountHandler> auto_mount_handlers_; @@ -412,7 +413,7 @@ class STORAGE_EXPORT FileSystemContext bool is_incognito_; - scoped_ptr<FileSystemOperationRunner> operation_runner_; + std::unique_ptr<FileSystemOperationRunner> operation_runner_; DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemContext); }; diff --git a/chromium/storage/browser/fileapi/file_system_file_stream_reader.cc b/chromium/storage/browser/fileapi/file_system_file_stream_reader.cc index 0f30eb34517..1b749bed690 100644 --- a/chromium/storage/browser/fileapi/file_system_file_stream_reader.cc +++ b/chromium/storage/browser/fileapi/file_system_file_stream_reader.cc @@ -69,10 +69,9 @@ int FileSystemFileStreamReader::Read( const net::CompletionCallback& callback) { if (local_file_reader_) return local_file_reader_->Read(buf, buf_len, callback); - return CreateSnapshot( - base::Bind(&ReadAdapter, weak_factory_.GetWeakPtr(), - make_scoped_refptr(buf), buf_len, callback), - callback); + return CreateSnapshot(base::Bind(&ReadAdapter, weak_factory_.GetWeakPtr(), + base::RetainedRef(buf), buf_len, callback), + callback); } int64_t FileSystemFileStreamReader::GetLength( diff --git a/chromium/storage/browser/fileapi/file_system_file_stream_reader.h b/chromium/storage/browser/fileapi/file_system_file_stream_reader.h index 91c3c88e87f..a65a73677e6 100644 --- a/chromium/storage/browser/fileapi/file_system_file_stream_reader.h +++ b/chromium/storage/browser/fileapi/file_system_file_stream_reader.h @@ -7,6 +7,8 @@ #include <stdint.h> +#include <memory> + #include "base/bind.h" #include "base/files/file.h" #include "base/macros.h" @@ -69,7 +71,7 @@ class STORAGE_EXPORT FileSystemFileStreamReader FileSystemURL url_; const int64_t initial_offset_; const base::Time expected_modification_time_; - scoped_ptr<storage::FileStreamReader> local_file_reader_; + std::unique_ptr<storage::FileStreamReader> local_file_reader_; scoped_refptr<storage::ShareableFileReference> snapshot_ref_; bool has_pending_create_snapshot_; base::WeakPtrFactory<FileSystemFileStreamReader> weak_factory_; diff --git a/chromium/storage/browser/fileapi/file_system_file_util.h b/chromium/storage/browser/fileapi/file_system_file_util.h index 5336277665e..b2fd8744f56 100644 --- a/chromium/storage/browser/fileapi/file_system_file_util.h +++ b/chromium/storage/browser/fileapi/file_system_file_util.h @@ -7,10 +7,11 @@ #include <stdint.h> +#include <memory> + #include "base/files/file.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/blob/scoped_file.h" #include "storage/browser/fileapi/file_system_operation.h" #include "storage/browser/storage_browser_export.h" @@ -98,7 +99,7 @@ class STORAGE_EXPORT FileSystemFileUtil { // // The supplied context must remain valid at least lifetime of the enumerator // instance. - virtual scoped_ptr<AbstractFileEnumerator> CreateFileEnumerator( + virtual std::unique_ptr<AbstractFileEnumerator> CreateFileEnumerator( FileSystemOperationContext* context, const FileSystemURL& root_url) = 0; diff --git a/chromium/storage/browser/fileapi/file_system_operation.h b/chromium/storage/browser/fileapi/file_system_operation.h index 2ef9c9980b0..8f11c1e2a71 100644 --- a/chromium/storage/browser/fileapi/file_system_operation.h +++ b/chromium/storage/browser/fileapi/file_system_operation.h @@ -7,6 +7,7 @@ #include <stdint.h> +#include <memory> #include <vector> #include "base/callback.h" @@ -63,7 +64,7 @@ class FileSystemOperation { STORAGE_EXPORT static FileSystemOperation* Create( const FileSystemURL& url, FileSystemContext* file_system_context, - scoped_ptr<FileSystemOperationContext> operation_context); + std::unique_ptr<FileSystemOperationContext> operation_context); virtual ~FileSystemOperation() {} @@ -324,11 +325,10 @@ class FileSystemOperation { const StatusCallback& callback) = 0; // Writes the data read from |blob_request| using |writer_delegate|. - virtual void Write( - const FileSystemURL& url, - scoped_ptr<FileWriterDelegate> writer_delegate, - scoped_ptr<net::URLRequest> blob_request, - const WriteCallback& callback) = 0; + virtual void Write(const FileSystemURL& url, + std::unique_ptr<FileWriterDelegate> writer_delegate, + std::unique_ptr<net::URLRequest> blob_request, + const WriteCallback& callback) = 0; // Truncates a file at |path| to |length|. If |length| is larger than // the original file size, the file will be extended, and the extended diff --git a/chromium/storage/browser/fileapi/file_system_operation_impl.cc b/chromium/storage/browser/fileapi/file_system_operation_impl.cc index 15700f060c4..196f693da04 100644 --- a/chromium/storage/browser/fileapi/file_system_operation_impl.cc +++ b/chromium/storage/browser/fileapi/file_system_operation_impl.cc @@ -5,7 +5,10 @@ #include "storage/browser/fileapi/file_system_operation_impl.h" #include <stdint.h> + #include <limits> +#include <memory> +#include <tuple> #include <utility> #include "base/bind.h" @@ -57,7 +60,7 @@ void DidOpenFile( FileSystemOperation* FileSystemOperation::Create( const FileSystemURL& url, FileSystemContext* file_system_context, - scoped_ptr<FileSystemOperationContext> operation_context) { + std::unique_ptr<FileSystemOperationContext> operation_context) { return new FileSystemOperationImpl(url, file_system_context, std::move(operation_context)); } @@ -190,8 +193,8 @@ void FileSystemOperationImpl::Remove(const FileSystemURL& url, void FileSystemOperationImpl::Write( const FileSystemURL& url, - scoped_ptr<FileWriterDelegate> writer_delegate, - scoped_ptr<net::URLRequest> blob_request, + std::unique_ptr<FileWriterDelegate> writer_delegate, + std::unique_ptr<net::URLRequest> blob_request, const WriteCallback& callback) { DCHECK(SetPendingOperationType(kOperationWrite)); file_writer_delegate_ = std::move(writer_delegate); @@ -374,7 +377,7 @@ base::File::Error FileSystemOperationImpl::SyncGetPlatformPath( FileSystemOperationImpl::FileSystemOperationImpl( const FileSystemURL& url, FileSystemContext* file_system_context, - scoped_ptr<FileSystemOperationContext> operation_context) + std::unique_ptr<FileSystemOperationContext> operation_context) : file_system_context_(file_system_context), operation_context_(std::move(operation_context)), async_file_util_(NULL), @@ -581,7 +584,7 @@ void FileSystemOperationImpl::DidWrite( if (complete && write_status != FileWriterDelegate::ERROR_WRITE_NOT_STARTED) { DCHECK(operation_context_); operation_context_->change_observers()->Notify( - &FileChangeObserver::OnModifyFile, base::MakeTuple(url)); + &FileChangeObserver::OnModifyFile, std::make_tuple(url)); } StatusCallback cancel_callback = cancel_callback_; diff --git a/chromium/storage/browser/fileapi/file_system_operation_impl.h b/chromium/storage/browser/fileapi/file_system_operation_impl.h index de660f45b6a..77e924887c4 100644 --- a/chromium/storage/browser/fileapi/file_system_operation_impl.h +++ b/chromium/storage/browser/fileapi/file_system_operation_impl.h @@ -7,11 +7,11 @@ #include <stdint.h> +#include <memory> #include <vector> #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "storage/browser/blob/scoped_file.h" #include "storage/browser/fileapi/file_system_operation.h" @@ -64,8 +64,8 @@ class STORAGE_EXPORT FileSystemOperationImpl bool recursive, const StatusCallback& callback) override; void Write(const FileSystemURL& url, - scoped_ptr<FileWriterDelegate> writer_delegate, - scoped_ptr<net::URLRequest> blob_request, + std::unique_ptr<FileWriterDelegate> writer_delegate, + std::unique_ptr<net::URLRequest> blob_request, const WriteCallback& callback) override; void Truncate(const FileSystemURL& url, int64_t length, @@ -109,7 +109,7 @@ class STORAGE_EXPORT FileSystemOperationImpl FileSystemOperationImpl( const FileSystemURL& url, FileSystemContext* file_system_context, - scoped_ptr<FileSystemOperationContext> operation_context); + std::unique_ptr<FileSystemOperationContext> operation_context); // Queries the quota and usage and then runs the given |task|. // If an error occurs during the quota query it runs |error_callback| instead. @@ -188,11 +188,11 @@ class STORAGE_EXPORT FileSystemOperationImpl scoped_refptr<FileSystemContext> file_system_context_; - scoped_ptr<FileSystemOperationContext> operation_context_; + std::unique_ptr<FileSystemOperationContext> operation_context_; AsyncFileUtil* async_file_util_; // Not owned. - scoped_ptr<FileWriterDelegate> file_writer_delegate_; - scoped_ptr<RecursiveOperationDelegate> recursive_operation_delegate_; + std::unique_ptr<FileWriterDelegate> file_writer_delegate_; + std::unique_ptr<RecursiveOperationDelegate> recursive_operation_delegate_; StatusCallback cancel_callback_; diff --git a/chromium/storage/browser/fileapi/file_system_operation_runner.cc b/chromium/storage/browser/fileapi/file_system_operation_runner.cc index 20a957b8d46..665d7f040de 100644 --- a/chromium/storage/browser/fileapi/file_system_operation_runner.cc +++ b/chromium/storage/browser/fileapi/file_system_operation_runner.cc @@ -5,6 +5,9 @@ #include "storage/browser/fileapi/file_system_operation_runner.h" #include <stdint.h> + +#include <memory> +#include <tuple> #include <utility> #include "base/bind.h" @@ -33,6 +36,8 @@ class FileSystemOperationRunner::BeginOperationScoper }; FileSystemOperationRunner::OperationHandle::OperationHandle() {} +FileSystemOperationRunner::OperationHandle::OperationHandle( + const OperationHandle& other) = default; FileSystemOperationRunner::OperationHandle::~OperationHandle() {} FileSystemOperationRunner::~FileSystemOperationRunner() { @@ -241,7 +246,7 @@ OperationID FileSystemOperationRunner::Remove( OperationID FileSystemOperationRunner::Write( const net::URLRequestContext* url_request_context, const FileSystemURL& url, - scoped_ptr<storage::BlobDataHandle> blob, + std::unique_ptr<storage::BlobDataHandle> blob, int64_t offset, const WriteCallback& callback) { base::File::Error error = base::File::FILE_OK; @@ -255,7 +260,7 @@ OperationID FileSystemOperationRunner::Write( return handle.id; } - scoped_ptr<FileStreamWriter> writer( + std::unique_ptr<FileStreamWriter> writer( file_system_context_->CreateFileStreamWriter(url, offset)); if (!writer) { // Write is not supported. @@ -263,10 +268,10 @@ OperationID FileSystemOperationRunner::Write( return handle.id; } - scoped_ptr<FileWriterDelegate> writer_delegate(new FileWriterDelegate( + std::unique_ptr<FileWriterDelegate> writer_delegate(new FileWriterDelegate( std::move(writer), url.mount_option().flush_policy())); - scoped_ptr<net::URLRequest> blob_request( + std::unique_ptr<net::URLRequest> blob_request( storage::BlobProtocolHandler::CreateBlobRequest( std::move(blob), url_request_context, writer_delegate.get())); @@ -500,7 +505,7 @@ base::File::Error FileSystemOperationRunner::SyncGetPlatformPath( const FileSystemURL& url, base::FilePath* platform_path) { base::File::Error error = base::File::FILE_OK; - scoped_ptr<FileSystemOperation> operation( + std::unique_ptr<FileSystemOperation> operation( file_system_context_->CreateFileSystemOperation(url, &error)); if (!operation.get()) return error; @@ -635,7 +640,7 @@ void FileSystemOperationRunner::PrepareForWrite(OperationID id, const FileSystemURL& url) { if (file_system_context_->GetUpdateObservers(url.type())) { file_system_context_->GetUpdateObservers(url.type())->Notify( - &FileUpdateObserver::OnStartUpdate, base::MakeTuple(url)); + &FileUpdateObserver::OnStartUpdate, std::make_tuple(url)); } write_target_urls_[id].insert(url); } @@ -644,7 +649,7 @@ void FileSystemOperationRunner::PrepareForRead(OperationID id, const FileSystemURL& url) { if (file_system_context_->GetAccessObservers(url.type())) { file_system_context_->GetAccessObservers(url.type())->Notify( - &FileAccessObserver::OnAccess, base::MakeTuple(url)); + &FileAccessObserver::OnAccess, std::make_tuple(url)); } } @@ -666,7 +671,7 @@ void FileSystemOperationRunner::FinishOperation(OperationID id) { iter != urls.end(); ++iter) { if (file_system_context_->GetUpdateObservers(iter->type())) { file_system_context_->GetUpdateObservers(iter->type())->Notify( - &FileUpdateObserver::OnEndUpdate, base::MakeTuple(*iter)); + &FileUpdateObserver::OnEndUpdate, std::make_tuple(*iter)); } } write_target_urls_.erase(found); diff --git a/chromium/storage/browser/fileapi/file_system_operation_runner.h b/chromium/storage/browser/fileapi/file_system_operation_runner.h index dabe8f18bff..621a7d9b28e 100644 --- a/chromium/storage/browser/fileapi/file_system_operation_runner.h +++ b/chromium/storage/browser/fileapi/file_system_operation_runner.h @@ -8,12 +8,12 @@ #include <stdint.h> #include <map> +#include <memory> #include <set> #include <vector> #include "base/id_map.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "storage/browser/blob/blob_data_handle.h" #include "storage/browser/fileapi/file_system_operation.h" @@ -117,7 +117,7 @@ class STORAGE_EXPORT FileSystemOperationRunner // |url_request_context| is used to read contents in |blob|. OperationID Write(const net::URLRequestContext* url_request_context, const FileSystemURL& url, - scoped_ptr<storage::BlobDataHandle> blob, + std::unique_ptr<storage::BlobDataHandle> blob, int64_t offset, const WriteCallback& callback); @@ -252,6 +252,7 @@ class STORAGE_EXPORT FileSystemOperationRunner base::WeakPtr<BeginOperationScoper> scope; OperationHandle(); + OperationHandle(const OperationHandle& other); ~OperationHandle(); }; diff --git a/chromium/storage/browser/fileapi/file_system_options.cc b/chromium/storage/browser/fileapi/file_system_options.cc index 47fc3d01f9c..8037111c619 100644 --- a/chromium/storage/browser/fileapi/file_system_options.cc +++ b/chromium/storage/browser/fileapi/file_system_options.cc @@ -15,6 +15,8 @@ FileSystemOptions::FileSystemOptions( env_override_(env_override) { } +FileSystemOptions::FileSystemOptions(const FileSystemOptions& other) = default; + FileSystemOptions::~FileSystemOptions() { } diff --git a/chromium/storage/browser/fileapi/file_system_options.h b/chromium/storage/browser/fileapi/file_system_options.h index 6e15baf9af6..717d60c01b8 100644 --- a/chromium/storage/browser/fileapi/file_system_options.h +++ b/chromium/storage/browser/fileapi/file_system_options.h @@ -35,6 +35,7 @@ class STORAGE_EXPORT FileSystemOptions { ProfileMode profile_mode, const std::vector<std::string>& additional_allowed_schemes, leveldb::Env* env_override); + FileSystemOptions(const FileSystemOptions& other); ~FileSystemOptions(); diff --git a/chromium/storage/browser/fileapi/file_system_quota_client.cc b/chromium/storage/browser/fileapi/file_system_quota_client.cc index b988a99e514..26fde452d6a 100644 --- a/chromium/storage/browser/fileapi/file_system_quota_client.cc +++ b/chromium/storage/browser/fileapi/file_system_quota_client.cc @@ -5,16 +5,15 @@ #include "storage/browser/fileapi/file_system_quota_client.h" #include <algorithm> +#include <memory> #include "base/bind.h" #include "base/files/file_util.h" #include "base/location.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/task_runner_util.h" -#include "net/base/net_util.h" #include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/fileapi/file_system_usage_cache.h" #include "storage/browser/fileapi/sandbox_file_system_backend.h" @@ -115,14 +114,11 @@ void FileSystemQuotaClient::GetOriginUsage( } base::PostTaskAndReplyWithResult( - file_task_runner(), - FROM_HERE, + file_task_runner(), FROM_HERE, // It is safe to pass Unretained(quota_util) since context owns it. base::Bind(&FileSystemQuotaUtil::GetOriginUsageOnFileTaskRunner, base::Unretained(quota_util), - file_system_context_, - origin_url, - type), + base::RetainedRef(file_system_context_), origin_url, type), callback); } @@ -140,14 +136,10 @@ void FileSystemQuotaClient::GetOriginsForType( std::set<GURL>* origins_ptr = new std::set<GURL>(); file_task_runner()->PostTaskAndReply( - FROM_HERE, - base::Bind(&GetOriginsForTypeOnFileTaskRunner, - file_system_context_, - storage_type, - base::Unretained(origins_ptr)), - base::Bind(&DidGetOrigins, - callback, - base::Owned(origins_ptr))); + FROM_HERE, base::Bind(&GetOriginsForTypeOnFileTaskRunner, + base::RetainedRef(file_system_context_), + storage_type, base::Unretained(origins_ptr)), + base::Bind(&DidGetOrigins, callback, base::Owned(origins_ptr))); } void FileSystemQuotaClient::GetOriginsForHost( @@ -165,15 +157,10 @@ void FileSystemQuotaClient::GetOriginsForHost( std::set<GURL>* origins_ptr = new std::set<GURL>(); file_task_runner()->PostTaskAndReply( - FROM_HERE, - base::Bind(&GetOriginsForHostOnFileTaskRunner, - file_system_context_, - storage_type, - host, - base::Unretained(origins_ptr)), - base::Bind(&DidGetOrigins, - callback, - base::Owned(origins_ptr))); + FROM_HERE, base::Bind(&GetOriginsForHostOnFileTaskRunner, + base::RetainedRef(file_system_context_), + storage_type, host, base::Unretained(origins_ptr)), + base::Bind(&DidGetOrigins, callback, base::Owned(origins_ptr))); } void FileSystemQuotaClient::DeleteOriginData( @@ -184,12 +171,9 @@ void FileSystemQuotaClient::DeleteOriginData( DCHECK(fs_type != kFileSystemTypeUnknown); base::PostTaskAndReplyWithResult( - file_task_runner(), - FROM_HERE, + file_task_runner(), FROM_HERE, base::Bind(&DeleteOriginOnFileTaskRunner, - file_system_context_, - origin, - fs_type), + base::RetainedRef(file_system_context_), origin, fs_type), callback); } diff --git a/chromium/storage/browser/fileapi/file_system_url.cc b/chromium/storage/browser/fileapi/file_system_url.cc index 13baad42b23..f1798d87527 100644 --- a/chromium/storage/browser/fileapi/file_system_url.cc +++ b/chromium/storage/browser/fileapi/file_system_url.cc @@ -24,6 +24,8 @@ FileSystemURL::FileSystemURL() mount_option_(FlushPolicy::NO_FLUSH_ON_COMPLETION) { } +FileSystemURL::FileSystemURL(const FileSystemURL& other) = default; + // static FileSystemURL FileSystemURL::CreateForTest(const GURL& url) { return FileSystemURL(url); diff --git a/chromium/storage/browser/fileapi/file_system_url.h b/chromium/storage/browser/fileapi/file_system_url.h index aca3cc00353..b9e8a9951da 100644 --- a/chromium/storage/browser/fileapi/file_system_url.h +++ b/chromium/storage/browser/fileapi/file_system_url.h @@ -78,6 +78,7 @@ namespace storage { class STORAGE_EXPORT FileSystemURL { public: FileSystemURL(); + FileSystemURL(const FileSystemURL& other); ~FileSystemURL(); // Methods for creating FileSystemURL without attempting to crack them. diff --git a/chromium/storage/browser/fileapi/file_system_url_request_job.cc b/chromium/storage/browser/fileapi/file_system_url_request_job.cc index 48ce68e729e..28b9ea69822 100644 --- a/chromium/storage/browser/fileapi/file_system_url_request_job.cc +++ b/chromium/storage/browser/fileapi/file_system_url_request_job.cc @@ -21,7 +21,6 @@ #include "net/base/io_buffer.h" #include "net/base/mime_util.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" #include "net/http/http_util.h" diff --git a/chromium/storage/browser/fileapi/file_system_url_request_job.h b/chromium/storage/browser/fileapi/file_system_url_request_job.h index c06a34b066f..183ef434bac 100644 --- a/chromium/storage/browser/fileapi/file_system_url_request_job.h +++ b/chromium/storage/browser/fileapi/file_system_url_request_job.h @@ -7,12 +7,12 @@ #include <stdint.h> +#include <memory> #include <string> #include "base/files/file.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "net/base/net_errors.h" #include "net/http/http_byte_range.h" @@ -67,10 +67,10 @@ class STORAGE_EXPORT FileSystemURLRequestJob : public net::URLRequestJob { const std::string storage_domain_; FileSystemContext* file_system_context_; - scoped_ptr<storage::FileStreamReader> reader_; + std::unique_ptr<storage::FileStreamReader> reader_; FileSystemURL url_; bool is_directory_; - scoped_ptr<net::HttpResponseInfo> response_info_; + std::unique_ptr<net::HttpResponseInfo> response_info_; int64_t remaining_bytes_; net::Error range_parse_result_; net::HttpByteRange byte_range_; diff --git a/chromium/storage/browser/fileapi/file_system_usage_cache.h b/chromium/storage/browser/fileapi/file_system_usage_cache.h index c4d5474e1e4..2ce570cbe31 100644 --- a/chromium/storage/browser/fileapi/file_system_usage_cache.h +++ b/chromium/storage/browser/fileapi/file_system_usage_cache.h @@ -8,11 +8,11 @@ #include <stdint.h> #include <map> +#include <memory> #include "base/files/file.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" #include "storage/browser/storage_browser_export.h" @@ -92,7 +92,7 @@ class STORAGE_EXPORT FileSystemUsageCache { bool CalledOnValidThread(); - scoped_ptr<TimedTaskHelper> timer_; + std::unique_ptr<TimedTaskHelper> timer_; CacheFiles cache_files_; scoped_refptr<base::SequencedTaskRunner> task_runner_; diff --git a/chromium/storage/browser/fileapi/file_writer_delegate.cc b/chromium/storage/browser/fileapi/file_writer_delegate.cc index 2b1354e3940..2050ca0b135 100644 --- a/chromium/storage/browser/fileapi/file_writer_delegate.cc +++ b/chromium/storage/browser/fileapi/file_writer_delegate.cc @@ -5,6 +5,8 @@ #include "storage/browser/fileapi/file_writer_delegate.h" #include <stdint.h> + +#include <memory> #include <utility> #include "base/bind.h" @@ -24,7 +26,7 @@ namespace storage { static const int kReadBufSize = 32768; FileWriterDelegate::FileWriterDelegate( - scoped_ptr<FileStreamWriter> file_stream_writer, + std::unique_ptr<FileStreamWriter> file_stream_writer, FlushPolicy flush_policy) : file_stream_writer_(std::move(file_stream_writer)), writing_started_(false), @@ -38,7 +40,7 @@ FileWriterDelegate::FileWriterDelegate( FileWriterDelegate::~FileWriterDelegate() { } -void FileWriterDelegate::Start(scoped_ptr<net::URLRequest> request, +void FileWriterDelegate::Start(std::unique_ptr<net::URLRequest> request, const DelegateWriteCallback& write_callback) { write_callback_ = write_callback; request_ = std::move(request); diff --git a/chromium/storage/browser/fileapi/file_writer_delegate.h b/chromium/storage/browser/fileapi/file_writer_delegate.h index 2e58e2552d2..2323ea5cbdd 100644 --- a/chromium/storage/browser/fileapi/file_writer_delegate.h +++ b/chromium/storage/browser/fileapi/file_writer_delegate.h @@ -7,10 +7,11 @@ #include <stdint.h> +#include <memory> + #include "base/files/file.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "net/base/file_stream.h" @@ -37,11 +38,11 @@ class STORAGE_EXPORT FileWriterDelegate : public net::URLRequest::Delegate { WriteProgressStatus write_status)> DelegateWriteCallback; - FileWriterDelegate(scoped_ptr<FileStreamWriter> file_writer, + FileWriterDelegate(std::unique_ptr<FileStreamWriter> file_writer, FlushPolicy flush_policy); ~FileWriterDelegate() override; - void Start(scoped_ptr<net::URLRequest> request, + void Start(std::unique_ptr<net::URLRequest> request, const DelegateWriteCallback& write_callback); // Cancels the current write operation. This will synchronously or @@ -64,10 +65,9 @@ class STORAGE_EXPORT FileWriterDelegate : public net::URLRequest::Delegate { void OnReadCompleted(net::URLRequest* request, int bytes_read) override; private: - void OnGetFileInfoAndStartRequest( - scoped_ptr<net::URLRequest> request, - base::File::Error error, - const base::File::Info& file_info); + void OnGetFileInfoAndStartRequest(std::unique_ptr<net::URLRequest> request, + base::File::Error error, + const base::File::Info& file_info); void Read(); void OnDataReceived(int bytes_read); void Write(); @@ -86,7 +86,7 @@ class STORAGE_EXPORT FileWriterDelegate : public net::URLRequest::Delegate { WriteProgressStatus GetCompletionStatusOnError() const; DelegateWriteCallback write_callback_; - scoped_ptr<FileStreamWriter> file_stream_writer_; + std::unique_ptr<FileStreamWriter> file_stream_writer_; base::Time last_progress_event_time_; bool writing_started_; FlushPolicy flush_policy_; @@ -95,7 +95,7 @@ class STORAGE_EXPORT FileWriterDelegate : public net::URLRequest::Delegate { int bytes_read_; scoped_refptr<net::IOBufferWithSize> io_buffer_; scoped_refptr<net::DrainableIOBuffer> cursor_; - scoped_ptr<net::URLRequest> request_; + std::unique_ptr<net::URLRequest> request_; base::WeakPtrFactory<FileWriterDelegate> weak_factory_; diff --git a/chromium/storage/browser/fileapi/isolated_file_system_backend.cc b/chromium/storage/browser/fileapi/isolated_file_system_backend.cc index bd8d9bf4466..5295a506880 100644 --- a/chromium/storage/browser/fileapi/isolated_file_system_backend.cc +++ b/chromium/storage/browser/fileapi/isolated_file_system_backend.cc @@ -6,12 +6,14 @@ #include <stdint.h> +#include <memory> #include <string> #include "base/bind.h" #include "base/files/file_path.h" #include "base/files/file_util_proxy.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" #include "base/thread_task_runner_handle.h" #include "storage/browser/fileapi/async_file_util_adapter.h" @@ -108,7 +110,7 @@ FileSystemOperation* IsolatedFileSystemBackend::CreateFileSystemOperation( FileSystemContext* context, base::File::Error* error_code) const { return FileSystemOperation::Create( - url, context, make_scoped_ptr(new FileSystemOperationContext(context))); + url, context, base::WrapUnique(new FileSystemOperationContext(context))); } bool IsolatedFileSystemBackend::SupportsStreaming( @@ -123,31 +125,27 @@ bool IsolatedFileSystemBackend::HasInplaceCopyImplementation( return false; } -scoped_ptr<storage::FileStreamReader> +std::unique_ptr<storage::FileStreamReader> IsolatedFileSystemBackend::CreateFileStreamReader( const FileSystemURL& url, int64_t offset, int64_t max_bytes_to_read, const base::Time& expected_modification_time, FileSystemContext* context) const { - return scoped_ptr<storage::FileStreamReader>( + return std::unique_ptr<storage::FileStreamReader>( storage::FileStreamReader::CreateForLocalFile( - context->default_file_task_runner(), - url.path(), - offset, + context->default_file_task_runner(), url.path(), offset, expected_modification_time)); } -scoped_ptr<FileStreamWriter> IsolatedFileSystemBackend::CreateFileStreamWriter( +std::unique_ptr<FileStreamWriter> +IsolatedFileSystemBackend::CreateFileStreamWriter( const FileSystemURL& url, int64_t offset, FileSystemContext* context) const { - return scoped_ptr<FileStreamWriter>( - FileStreamWriter::CreateForLocalFile( - context->default_file_task_runner(), - url.path(), - offset, - FileStreamWriter::OPEN_EXISTING_FILE)); + return std::unique_ptr<FileStreamWriter>(FileStreamWriter::CreateForLocalFile( + context->default_file_task_runner(), url.path(), offset, + FileStreamWriter::OPEN_EXISTING_FILE)); } FileSystemQuotaUtil* IsolatedFileSystemBackend::GetQuotaUtil() { diff --git a/chromium/storage/browser/fileapi/isolated_file_system_backend.h b/chromium/storage/browser/fileapi/isolated_file_system_backend.h index 2e00818cf49..62321fa53bd 100644 --- a/chromium/storage/browser/fileapi/isolated_file_system_backend.h +++ b/chromium/storage/browser/fileapi/isolated_file_system_backend.h @@ -7,7 +7,8 @@ #include <stdint.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "storage/browser/fileapi/file_system_backend.h" #include "storage/browser/fileapi/task_runner_bound_observer_list.h" @@ -39,13 +40,13 @@ class IsolatedFileSystemBackend : public FileSystemBackend { bool SupportsStreaming(const FileSystemURL& url) const override; bool HasInplaceCopyImplementation( storage::FileSystemType type) const override; - scoped_ptr<storage::FileStreamReader> CreateFileStreamReader( + std::unique_ptr<storage::FileStreamReader> CreateFileStreamReader( const FileSystemURL& url, int64_t offset, int64_t max_bytes_to_read, const base::Time& expected_modification_time, FileSystemContext* context) const override; - scoped_ptr<FileStreamWriter> CreateFileStreamWriter( + std::unique_ptr<FileStreamWriter> CreateFileStreamWriter( const FileSystemURL& url, int64_t offset, FileSystemContext* context) const override; @@ -66,9 +67,9 @@ class IsolatedFileSystemBackend : public FileSystemBackend { // As above but for platform webapps. const bool use_for_type_platform_app_; - scoped_ptr<AsyncFileUtilAdapter> isolated_file_util_; - scoped_ptr<AsyncFileUtilAdapter> dragged_file_util_; - scoped_ptr<AsyncFileUtilAdapter> transient_file_util_; + std::unique_ptr<AsyncFileUtilAdapter> isolated_file_util_; + std::unique_ptr<AsyncFileUtilAdapter> dragged_file_util_; + std::unique_ptr<AsyncFileUtilAdapter> transient_file_util_; }; } // namespace storage diff --git a/chromium/storage/browser/fileapi/local_file_stream_reader.cc b/chromium/storage/browser/fileapi/local_file_stream_reader.cc index c6bfbbdc80d..74a9cc9bac2 100644 --- a/chromium/storage/browser/fileapi/local_file_stream_reader.cc +++ b/chromium/storage/browser/fileapi/local_file_stream_reader.cc @@ -43,8 +43,8 @@ int LocalFileStreamReader::Read(net::IOBuffer* buf, int buf_len, if (stream_impl_) return stream_impl_->Read(buf, buf_len, callback); return Open(base::Bind(&LocalFileStreamReader::DidOpenForRead, - weak_factory_.GetWeakPtr(), - make_scoped_refptr(buf), buf_len, callback)); + weak_factory_.GetWeakPtr(), base::RetainedRef(buf), + buf_len, callback)); } int64_t LocalFileStreamReader::GetLength( diff --git a/chromium/storage/browser/fileapi/local_file_stream_reader.h b/chromium/storage/browser/fileapi/local_file_stream_reader.h index 0f511bd2e26..9e9cd816686 100644 --- a/chromium/storage/browser/fileapi/local_file_stream_reader.h +++ b/chromium/storage/browser/fileapi/local_file_stream_reader.h @@ -7,6 +7,8 @@ #include <stdint.h> +#include <memory> + #include "base/compiler_specific.h" #include "base/files/file.h" #include "base/files/file_path.h" @@ -69,7 +71,7 @@ class STORAGE_EXPORT LocalFileStreamReader const base::File::Info& file_info); scoped_refptr<base::TaskRunner> task_runner_; - scoped_ptr<net::FileStream> stream_impl_; + std::unique_ptr<net::FileStream> stream_impl_; const base::FilePath file_path_; const int64_t initial_offset_; const base::Time expected_modification_time_; diff --git a/chromium/storage/browser/fileapi/local_file_stream_writer.cc b/chromium/storage/browser/fileapi/local_file_stream_writer.cc index e586fd17952..03ca22b8f8d 100644 --- a/chromium/storage/browser/fileapi/local_file_stream_writer.cc +++ b/chromium/storage/browser/fileapi/local_file_stream_writer.cc @@ -55,10 +55,10 @@ int LocalFileStreamWriter::Write(net::IOBuffer* buf, int buf_len, has_pending_operation_ = false; return result; } - return InitiateOpen(callback, - base::Bind(&LocalFileStreamWriter::ReadyToWrite, - weak_factory_.GetWeakPtr(), - make_scoped_refptr(buf), buf_len, callback)); + return InitiateOpen( + callback, base::Bind(&LocalFileStreamWriter::ReadyToWrite, + weak_factory_.GetWeakPtr(), base::RetainedRef(buf), + buf_len, callback)); } int LocalFileStreamWriter::Cancel(const net::CompletionCallback& callback) { diff --git a/chromium/storage/browser/fileapi/local_file_stream_writer.h b/chromium/storage/browser/fileapi/local_file_stream_writer.h index 43375e6e95b..dce2f805858 100644 --- a/chromium/storage/browser/fileapi/local_file_stream_writer.h +++ b/chromium/storage/browser/fileapi/local_file_stream_writer.h @@ -7,13 +7,13 @@ #include <stdint.h> +#include <memory> #include <utility> #include "base/callback.h" #include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/task_runner.h" #include "storage/browser/fileapi/file_stream_writer.h" @@ -91,7 +91,7 @@ class STORAGE_EXPORT LocalFileStreamWriter // Current states of the operation. bool has_pending_operation_; - scoped_ptr<net::FileStream> stream_impl_; + std::unique_ptr<net::FileStream> stream_impl_; net::CompletionCallback cancel_callback_; base::WeakPtrFactory<LocalFileStreamWriter> weak_factory_; diff --git a/chromium/storage/browser/fileapi/local_file_util.cc b/chromium/storage/browser/fileapi/local_file_util.cc index b63b44f02e8..02268996e2f 100644 --- a/chromium/storage/browser/fileapi/local_file_util.cc +++ b/chromium/storage/browser/fileapi/local_file_util.cc @@ -6,9 +6,12 @@ #include <stdint.h> +#include <memory> + #include "base/files/file_enumerator.h" #include "base/files/file_util.h" #include "base/files/file_util_proxy.h" +#include "base/memory/ptr_util.h" #include "storage/browser/fileapi/async_file_util_adapter.h" #include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/fileapi/file_system_operation_context.h" @@ -134,18 +137,16 @@ base::File::Error LocalFileUtil::GetFileInfo( return error; } -scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> LocalFileUtil:: - CreateFileEnumerator( - FileSystemOperationContext* context, - const FileSystemURL& root_url) { +std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> +LocalFileUtil::CreateFileEnumerator(FileSystemOperationContext* context, + const FileSystemURL& root_url) { base::FilePath file_path; if (GetLocalFilePath(context, root_url, &file_path) != base::File::FILE_OK) { - return make_scoped_ptr(new EmptyFileEnumerator); + return base::WrapUnique(new EmptyFileEnumerator); } - return make_scoped_ptr(new LocalFileEnumerator( - file_path, - root_url.path(), + return base::WrapUnique(new LocalFileEnumerator( + file_path, root_url.path(), base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES)); } diff --git a/chromium/storage/browser/fileapi/local_file_util.h b/chromium/storage/browser/fileapi/local_file_util.h index c1ae05ff457..f2ede6c7781 100644 --- a/chromium/storage/browser/fileapi/local_file_util.h +++ b/chromium/storage/browser/fileapi/local_file_util.h @@ -7,10 +7,11 @@ #include <stdint.h> +#include <memory> + #include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/fileapi/file_system_file_util.h" #include "storage/browser/storage_browser_export.h" @@ -46,7 +47,7 @@ class STORAGE_EXPORT LocalFileUtil const FileSystemURL& url, base::File::Info* file_info, base::FilePath* platform_file) override; - scoped_ptr<AbstractFileEnumerator> CreateFileEnumerator( + std::unique_ptr<AbstractFileEnumerator> CreateFileEnumerator( FileSystemOperationContext* context, const FileSystemURL& root_url) override; base::File::Error GetLocalFilePath(FileSystemOperationContext* context, diff --git a/chromium/storage/browser/fileapi/native_file_util.cc b/chromium/storage/browser/fileapi/native_file_util.cc index 852a02eab7a..aa2b6077115 100644 --- a/chromium/storage/browser/fileapi/native_file_util.cc +++ b/chromium/storage/browser/fileapi/native_file_util.cc @@ -6,8 +6,11 @@ #include <stdint.h> +#include <memory> + #include "base/files/file_enumerator.h" #include "base/files/file_util.h" +#include "base/memory/ptr_util.h" #include "storage/browser/fileapi/file_system_operation_context.h" #include "storage/browser/fileapi/file_system_url.h" #include "storage/common/fileapi/file_system_mount_option.h" @@ -205,12 +208,11 @@ base::File::Error NativeFileUtil::GetFileInfo( return base::File::FILE_OK; } -scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> - NativeFileUtil::CreateFileEnumerator(const base::FilePath& root_path, - bool recursive) { - return make_scoped_ptr(new NativeFileEnumerator( - root_path, - recursive, +std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> +NativeFileUtil::CreateFileEnumerator(const base::FilePath& root_path, + bool recursive) { + return base::WrapUnique(new NativeFileEnumerator( + root_path, recursive, base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES)); } diff --git a/chromium/storage/browser/fileapi/native_file_util.h b/chromium/storage/browser/fileapi/native_file_util.h index c1fea3f7e46..046c4b740d2 100644 --- a/chromium/storage/browser/fileapi/native_file_util.h +++ b/chromium/storage/browser/fileapi/native_file_util.h @@ -7,11 +7,12 @@ #include <stdint.h> +#include <memory> + #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/file_util_proxy.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/fileapi/file_system_file_util.h" #include "storage/browser/storage_browser_export.h" @@ -50,9 +51,8 @@ class STORAGE_EXPORT NativeFileUtil { bool recursive); static base::File::Error GetFileInfo(const base::FilePath& path, base::File::Info* file_info); - static scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> - CreateFileEnumerator(const base::FilePath& root_path, - bool recursive); + static std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> + CreateFileEnumerator(const base::FilePath& root_path, bool recursive); static base::File::Error Touch(const base::FilePath& path, const base::Time& last_access_time, const base::Time& last_modified_time); diff --git a/chromium/storage/browser/fileapi/obfuscated_file_util.cc b/chromium/storage/browser/fileapi/obfuscated_file_util.cc index cdd8b7a5b6d..009ba44020b 100644 --- a/chromium/storage/browser/fileapi/obfuscated_file_util.cc +++ b/chromium/storage/browser/fileapi/obfuscated_file_util.cc @@ -7,7 +7,9 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <queue> +#include <tuple> #include "base/files/file_util.h" #include "base/format_macros.h" @@ -91,7 +93,7 @@ void UpdateUsage(FileSystemOperationContext* context, const FileSystemURL& url, int64_t growth) { context->update_observers()->Notify( - &FileUpdateObserver::OnUpdate, base::MakeTuple(url, growth)); + &FileUpdateObserver::OnUpdate, std::make_tuple(url, growth)); } void TouchDirectory(SandboxDirectoryDatabase* db, FileId dir_id) { @@ -322,7 +324,7 @@ base::File::Error ObfuscatedFileUtil::EnsureFileExists( *created = true; UpdateUsage(context, url, growth); context->change_observers()->Notify( - &FileChangeObserver::OnCreateFile, base::MakeTuple(url)); + &FileChangeObserver::OnCreateFile, std::make_tuple(url)); } return error; } @@ -381,7 +383,7 @@ base::File::Error ObfuscatedFileUtil::CreateDirectory( return error; UpdateUsage(context, url, growth); context->change_observers()->Notify( - &FileChangeObserver::OnCreateDirectory, base::MakeTuple(url)); + &FileChangeObserver::OnCreateDirectory, std::make_tuple(url)); if (first) { first = false; TouchDirectory(db, file_info.parent_id); @@ -407,10 +409,9 @@ base::File::Error ObfuscatedFileUtil::GetFileInfo( file_info, platform_file_path); } -scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> - ObfuscatedFileUtil::CreateFileEnumerator( - FileSystemOperationContext* context, - const FileSystemURL& root_url) { +std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> +ObfuscatedFileUtil::CreateFileEnumerator(FileSystemOperationContext* context, + const FileSystemURL& root_url) { return CreateFileEnumerator(context, root_url, false /* recursive */); } @@ -482,7 +483,7 @@ base::File::Error ObfuscatedFileUtil::Truncate( if (error == base::File::FILE_OK) { UpdateUsage(context, url, growth); context->change_observers()->Notify( - &FileChangeObserver::OnModifyFile, base::MakeTuple(url)); + &FileChangeObserver::OnModifyFile, std::make_tuple(url)); } return error; } @@ -609,16 +610,16 @@ base::File::Error ObfuscatedFileUtil::CopyOrMoveFile( if (overwrite) { context->change_observers()->Notify( &FileChangeObserver::OnModifyFile, - base::MakeTuple(dest_url)); + std::make_tuple(dest_url)); } else { context->change_observers()->Notify( &FileChangeObserver::OnCreateFileFrom, - base::MakeTuple(dest_url, src_url)); + std::make_tuple(dest_url, src_url)); } if (!copy) { context->change_observers()->Notify( - &FileChangeObserver::OnRemoveFile, base::MakeTuple(src_url)); + &FileChangeObserver::OnRemoveFile, std::make_tuple(src_url)); TouchDirectory(db, src_file_info.parent_id); } @@ -697,10 +698,10 @@ base::File::Error ObfuscatedFileUtil::CopyInForeignFile( if (overwrite) { context->change_observers()->Notify( - &FileChangeObserver::OnModifyFile, base::MakeTuple(dest_url)); + &FileChangeObserver::OnModifyFile, std::make_tuple(dest_url)); } else { context->change_observers()->Notify( - &FileChangeObserver::OnCreateFile, base::MakeTuple(dest_url)); + &FileChangeObserver::OnCreateFile, std::make_tuple(dest_url)); } UpdateUsage(context, dest_url, growth); @@ -741,7 +742,7 @@ base::File::Error ObfuscatedFileUtil::DeleteFile( TouchDirectory(db, file_info.parent_id); context->change_observers()->Notify( - &FileChangeObserver::OnRemoveFile, base::MakeTuple(url)); + &FileChangeObserver::OnRemoveFile, std::make_tuple(url)); if (error == base::File::FILE_ERROR_NOT_FOUND) return base::File::FILE_OK; @@ -776,7 +777,7 @@ base::File::Error ObfuscatedFileUtil::DeleteDirectory( UpdateUsage(context, url, growth); TouchDirectory(db, file_info.parent_id); context->change_observers()->Notify( - &FileChangeObserver::OnRemoveDirectory, base::MakeTuple(url)); + &FileChangeObserver::OnRemoveDirectory, std::make_tuple(url)); return base::File::FILE_OK; } @@ -795,16 +796,15 @@ storage::ScopedFile ObfuscatedFileUtil::CreateSnapshotFile( return storage::ScopedFile(); } -scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> - ObfuscatedFileUtil::CreateFileEnumerator( - FileSystemOperationContext* context, - const FileSystemURL& root_url, - bool recursive) { +std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> +ObfuscatedFileUtil::CreateFileEnumerator(FileSystemOperationContext* context, + const FileSystemURL& root_url, + bool recursive) { SandboxDirectoryDatabase* db = GetDirectoryDatabase(root_url, false); if (!db) { - return scoped_ptr<AbstractFileEnumerator>(new EmptyFileEnumerator()); + return std::unique_ptr<AbstractFileEnumerator>(new EmptyFileEnumerator()); } - return scoped_ptr<AbstractFileEnumerator>( + return std::unique_ptr<AbstractFileEnumerator>( new ObfuscatedFileEnumerator(db, context, this, root_url, recursive)); } @@ -909,7 +909,7 @@ void ObfuscatedFileUtil::CloseFileSystemForOriginAndType( base::CompareCase::SENSITIVE)) break; DCHECK(type_string.empty() || iter->first == key_prefix); - scoped_ptr<SandboxDirectoryDatabase> database(iter->second); + std::unique_ptr<SandboxDirectoryDatabase> database(iter->second); directories_.erase(iter++); } } @@ -934,7 +934,7 @@ void ObfuscatedFileUtil::DestroyDirectoryDatabase( base::CompareCase::SENSITIVE)) break; DCHECK(type_string.empty() || iter->first == key_prefix); - scoped_ptr<SandboxDirectoryDatabase> database(iter->second); + std::unique_ptr<SandboxDirectoryDatabase> database(iter->second); directories_.erase(iter++); // Continue to destroy databases even if it failed because it doesn't affect @@ -969,7 +969,7 @@ void ObfuscatedFileUtil::MaybePrepopulateDatabase( origin, type_string, false, &error); if (error != base::File::FILE_OK) continue; - scoped_ptr<SandboxDirectoryDatabase> db( + std::unique_ptr<SandboxDirectoryDatabase> db( new SandboxDirectoryDatabase(path, env_override_)); if (db->Init(SandboxDirectoryDatabase::FAIL_ON_CORRUPTION)) { directories_[GetDirectoryDatabaseKey(origin, type_string)] = db.release(); @@ -1372,7 +1372,7 @@ base::File ObfuscatedFileUtil::CreateOrOpenInternal( if (file.IsValid()) { UpdateUsage(context, url, growth); context->change_observers()->Notify( - &FileChangeObserver::OnCreateFile, base::MakeTuple(url)); + &FileChangeObserver::OnCreateFile, std::make_tuple(url)); } return file; } @@ -1415,7 +1415,7 @@ base::File ObfuscatedFileUtil::CreateOrOpenInternal( if (delta) { UpdateUsage(context, url, delta); context->change_observers()->Notify( - &FileChangeObserver::OnModifyFile, base::MakeTuple(url)); + &FileChangeObserver::OnModifyFile, std::make_tuple(url)); } return file; } diff --git a/chromium/storage/browser/fileapi/obfuscated_file_util.h b/chromium/storage/browser/fileapi/obfuscated_file_util.h index e530ddb89c0..1ecfc4cdaa7 100644 --- a/chromium/storage/browser/fileapi/obfuscated_file_util.h +++ b/chromium/storage/browser/fileapi/obfuscated_file_util.h @@ -8,6 +8,7 @@ #include <stdint.h> #include <map> +#include <memory> #include <set> #include <string> #include <vector> @@ -17,7 +18,6 @@ #include "base/files/file_path.h" #include "base/files/file_util_proxy.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/blob/shareable_file_reference.h" #include "storage/browser/fileapi/file_system_file_util.h" #include "storage/browser/fileapi/file_system_url.h" @@ -126,7 +126,7 @@ class STORAGE_EXPORT ObfuscatedFileUtil : public FileSystemFileUtil { const FileSystemURL& url, base::File::Info* file_info, base::FilePath* platform_file) override; - scoped_ptr<AbstractFileEnumerator> CreateFileEnumerator( + std::unique_ptr<AbstractFileEnumerator> CreateFileEnumerator( FileSystemOperationContext* context, const FileSystemURL& root_url) override; base::File::Error GetLocalFilePath(FileSystemOperationContext* context, @@ -159,7 +159,7 @@ class STORAGE_EXPORT ObfuscatedFileUtil : public FileSystemFileUtil { base::FilePath* platform_path) override; // Same as the other CreateFileEnumerator, but with recursive support. - scoped_ptr<AbstractFileEnumerator> CreateFileEnumerator( + std::unique_ptr<AbstractFileEnumerator> CreateFileEnumerator( FileSystemOperationContext* context, const FileSystemURL& root_url, bool recursive); @@ -329,7 +329,7 @@ class STORAGE_EXPORT ObfuscatedFileUtil : public FileSystemFileUtil { typedef std::map<std::string, SandboxDirectoryDatabase*> DirectoryMap; DirectoryMap directories_; - scoped_ptr<SandboxOriginDatabaseInterface> origin_database_; + std::unique_ptr<SandboxOriginDatabaseInterface> origin_database_; scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_; base::FilePath file_system_directory_; leveldb::Env* env_override_; @@ -338,7 +338,7 @@ class STORAGE_EXPORT ObfuscatedFileUtil : public FileSystemFileUtil { int64_t db_flush_delay_seconds_; scoped_refptr<base::SequencedTaskRunner> file_task_runner_; - scoped_ptr<TimedTaskHelper> timer_; + std::unique_ptr<TimedTaskHelper> timer_; GetTypeStringForURLCallback get_type_string_for_url_; std::set<std::string> known_type_strings_; diff --git a/chromium/storage/browser/fileapi/plugin_private_file_system_backend.cc b/chromium/storage/browser/fileapi/plugin_private_file_system_backend.cc index 2eb36ff0d1a..6fd65cf32fb 100644 --- a/chromium/storage/browser/fileapi/plugin_private_file_system_backend.cc +++ b/chromium/storage/browser/fileapi/plugin_private_file_system_backend.cc @@ -5,14 +5,16 @@ #include "storage/browser/fileapi/plugin_private_file_system_backend.h" #include <stdint.h> + #include <map> +#include <memory> #include <utility> #include "base/stl_util.h" #include "base/synchronization/lock.h" #include "base/task_runner_util.h" #include "base/thread_task_runner_handle.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "storage/browser/fileapi/async_file_util_adapter.h" #include "storage/browser/fileapi/file_stream_reader.h" #include "storage/browser/fileapi/file_stream_writer.h" @@ -180,7 +182,7 @@ FileSystemOperation* PluginPrivateFileSystemBackend::CreateFileSystemOperation( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const { - scoped_ptr<FileSystemOperationContext> operation_context( + std::unique_ptr<FileSystemOperationContext> operation_context( new FileSystemOperationContext(context)); return FileSystemOperation::Create(url, context, std::move(operation_context)); @@ -196,22 +198,22 @@ bool PluginPrivateFileSystemBackend::HasInplaceCopyImplementation( return false; } -scoped_ptr<storage::FileStreamReader> +std::unique_ptr<storage::FileStreamReader> PluginPrivateFileSystemBackend::CreateFileStreamReader( const FileSystemURL& url, int64_t offset, int64_t max_bytes_to_read, const base::Time& expected_modification_time, FileSystemContext* context) const { - return scoped_ptr<storage::FileStreamReader>(); + return std::unique_ptr<storage::FileStreamReader>(); } -scoped_ptr<FileStreamWriter> +std::unique_ptr<FileStreamWriter> PluginPrivateFileSystemBackend::CreateFileStreamWriter( const FileSystemURL& url, int64_t offset, FileSystemContext* context) const { - return scoped_ptr<FileStreamWriter>(); + return std::unique_ptr<FileStreamWriter>(); } FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() { @@ -238,7 +240,7 @@ void PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileTaskRunner( std::set<GURL>* origins) { if (!CanHandleType(type)) return; - scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( + std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( obfuscated_file_util()->CreateOriginEnumerator()); GURL origin; while (!(origin = enumerator->Next()).is_empty()) @@ -251,7 +253,7 @@ void PluginPrivateFileSystemBackend::GetOriginsForHostOnFileTaskRunner( std::set<GURL>* origins) { if (!CanHandleType(type)) return; - scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( + std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( obfuscated_file_util()->CreateOriginEnumerator()); GURL origin; while (!(origin = enumerator->Next()).is_empty()) { diff --git a/chromium/storage/browser/fileapi/plugin_private_file_system_backend.h b/chromium/storage/browser/fileapi/plugin_private_file_system_backend.h index d2b17fd05a4..95ffb647147 100644 --- a/chromium/storage/browser/fileapi/plugin_private_file_system_backend.h +++ b/chromium/storage/browser/fileapi/plugin_private_file_system_backend.h @@ -7,6 +7,7 @@ #include <stdint.h> +#include <memory> #include <set> #include <string> @@ -81,13 +82,13 @@ class STORAGE_EXPORT PluginPrivateFileSystemBackend bool SupportsStreaming(const FileSystemURL& url) const override; bool HasInplaceCopyImplementation( storage::FileSystemType type) const override; - scoped_ptr<storage::FileStreamReader> CreateFileStreamReader( + std::unique_ptr<storage::FileStreamReader> CreateFileStreamReader( const FileSystemURL& url, int64_t offset, int64_t max_bytes_to_read, const base::Time& expected_modification_time, FileSystemContext* context) const override; - scoped_ptr<FileStreamWriter> CreateFileStreamWriter( + std::unique_ptr<FileStreamWriter> CreateFileStreamWriter( const FileSystemURL& url, int64_t offset, FileSystemContext* context) const override; @@ -126,7 +127,7 @@ class STORAGE_EXPORT PluginPrivateFileSystemBackend scoped_refptr<base::SequencedTaskRunner> file_task_runner_; const FileSystemOptions file_system_options_; const base::FilePath base_path_; - scoped_ptr<AsyncFileUtil> file_util_; + std::unique_ptr<AsyncFileUtil> file_util_; FileSystemIDToPluginMap* plugin_map_; // Owned by file_util_. base::WeakPtrFactory<PluginPrivateFileSystemBackend> weak_factory_; diff --git a/chromium/storage/browser/fileapi/quota/quota_reservation.cc b/chromium/storage/browser/fileapi/quota/quota_reservation.cc index f15e35e8bd2..e1a8ea0d728 100644 --- a/chromium/storage/browser/fileapi/quota/quota_reservation.cc +++ b/chromium/storage/browser/fileapi/quota/quota_reservation.cc @@ -6,6 +6,8 @@ #include <stdint.h> +#include <memory> + #include "base/bind.h" #include "storage/browser/fileapi/quota/open_file_handle.h" #include "storage/browser/fileapi/quota/quota_reservation_buffer.h" @@ -32,7 +34,7 @@ void QuotaReservation::RefreshReservation(int64_t size, remaining_quota_ = 0; } -scoped_ptr<OpenFileHandle> QuotaReservation::GetOpenFileHandle( +std::unique_ptr<OpenFileHandle> QuotaReservation::GetOpenFileHandle( const base::FilePath& platform_path) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); DCHECK(!client_crashed_); diff --git a/chromium/storage/browser/fileapi/quota/quota_reservation.h b/chromium/storage/browser/fileapi/quota/quota_reservation.h index 09151146289..61b0dd1e017 100644 --- a/chromium/storage/browser/fileapi/quota/quota_reservation.h +++ b/chromium/storage/browser/fileapi/quota/quota_reservation.h @@ -7,6 +7,8 @@ #include <stdint.h> +#include <memory> + #include "base/files/file.h" #include "base/files/file_path.h" #include "base/macros.h" @@ -38,7 +40,7 @@ class STORAGE_EXPORT QuotaReservation // Associates |platform_path| to the QuotaReservation instance. // Returns an OpenFileHandle instance that represents a quota managed file. - scoped_ptr<OpenFileHandle> GetOpenFileHandle( + std::unique_ptr<OpenFileHandle> GetOpenFileHandle( const base::FilePath& platform_path); // Should be called when the associated client is crashed. diff --git a/chromium/storage/browser/fileapi/quota/quota_reservation_buffer.cc b/chromium/storage/browser/fileapi/quota/quota_reservation_buffer.cc index 38b5a2a344b..6d6930af0e6 100644 --- a/chromium/storage/browser/fileapi/quota/quota_reservation_buffer.cc +++ b/chromium/storage/browser/fileapi/quota/quota_reservation_buffer.cc @@ -6,7 +6,10 @@ #include <stdint.h> +#include <memory> + #include "base/bind.h" +#include "base/memory/ptr_util.h" #include "storage/browser/fileapi/quota/open_file_handle.h" #include "storage/browser/fileapi/quota/open_file_handle_context.h" #include "storage/browser/fileapi/quota/quota_reservation.h" @@ -31,14 +34,14 @@ scoped_refptr<QuotaReservation> QuotaReservationBuffer::CreateReservation() { return make_scoped_refptr(new QuotaReservation(this)); } -scoped_ptr<OpenFileHandle> QuotaReservationBuffer::GetOpenFileHandle( +std::unique_ptr<OpenFileHandle> QuotaReservationBuffer::GetOpenFileHandle( QuotaReservation* reservation, const base::FilePath& platform_path) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); OpenFileHandleContext** open_file = &open_files_[platform_path]; if (!*open_file) *open_file = new OpenFileHandleContext(platform_path, this); - return make_scoped_ptr(new OpenFileHandle(reservation, *open_file)); + return base::WrapUnique(new OpenFileHandle(reservation, *open_file)); } void QuotaReservationBuffer::CommitFileGrowth( diff --git a/chromium/storage/browser/fileapi/quota/quota_reservation_buffer.h b/chromium/storage/browser/fileapi/quota/quota_reservation_buffer.h index 08031caf10b..b96388ec526 100644 --- a/chromium/storage/browser/fileapi/quota/quota_reservation_buffer.h +++ b/chromium/storage/browser/fileapi/quota/quota_reservation_buffer.h @@ -8,6 +8,7 @@ #include <stdint.h> #include <map> +#include <memory> #include "base/files/file.h" #include "base/files/file_path.h" @@ -40,7 +41,7 @@ class QuotaReservationBuffer : public base::RefCounted<QuotaReservationBuffer> { FileSystemType type); scoped_refptr<QuotaReservation> CreateReservation(); - scoped_ptr<OpenFileHandle> GetOpenFileHandle( + std::unique_ptr<OpenFileHandle> GetOpenFileHandle( QuotaReservation* reservation, const base::FilePath& platform_path); void CommitFileGrowth(int64_t quota_consumption, int64_t usage_delta); diff --git a/chromium/storage/browser/fileapi/quota/quota_reservation_manager.cc b/chromium/storage/browser/fileapi/quota/quota_reservation_manager.cc index c61b3b9533e..e182e7ec2da 100644 --- a/chromium/storage/browser/fileapi/quota/quota_reservation_manager.cc +++ b/chromium/storage/browser/fileapi/quota/quota_reservation_manager.cc @@ -5,6 +5,8 @@ #include "storage/browser/fileapi/quota/quota_reservation_manager.h" #include <stdint.h> + +#include <memory> #include <utility> #include "storage/browser/fileapi/quota/quota_reservation.h" @@ -13,7 +15,7 @@ namespace storage { QuotaReservationManager::QuotaReservationManager( - scoped_ptr<QuotaBackend> backend) + std::unique_ptr<QuotaBackend> backend) : backend_(std::move(backend)), weak_ptr_factory_(this) { sequence_checker_.DetachFromSequence(); } diff --git a/chromium/storage/browser/fileapi/quota/quota_reservation_manager.h b/chromium/storage/browser/fileapi/quota/quota_reservation_manager.h index 3a32ec7744e..fcd774e7c20 100644 --- a/chromium/storage/browser/fileapi/quota/quota_reservation_manager.h +++ b/chromium/storage/browser/fileapi/quota/quota_reservation_manager.h @@ -8,6 +8,7 @@ #include <stdint.h> #include <map> +#include <memory> #include <utility> #include "base/callback_forward.h" @@ -74,7 +75,7 @@ class STORAGE_EXPORT QuotaReservationManager { DISALLOW_COPY_AND_ASSIGN(QuotaBackend); }; - explicit QuotaReservationManager(scoped_ptr<QuotaBackend> backend); + explicit QuotaReservationManager(std::unique_ptr<QuotaBackend> backend); ~QuotaReservationManager(); // The entry point of the quota reservation. Creates new reservation object @@ -110,7 +111,7 @@ class STORAGE_EXPORT QuotaReservationManager { FileSystemType type); void ReleaseReservationBuffer(QuotaReservationBuffer* reservation_pool); - scoped_ptr<QuotaBackend> backend_; + std::unique_ptr<QuotaBackend> backend_; // Not owned. The destructor of ReservationBuffer should erase itself from // |reservation_buffers_| by calling ReleaseReservationBuffer. diff --git a/chromium/storage/browser/fileapi/recursive_operation_delegate.cc b/chromium/storage/browser/fileapi/recursive_operation_delegate.cc index a1e13fea34d..415953c69f5 100644 --- a/chromium/storage/browser/fileapi/recursive_operation_delegate.cc +++ b/chromium/storage/browser/fileapi/recursive_operation_delegate.cc @@ -14,15 +14,9 @@ namespace storage { -namespace { -// Don't start too many inflight operations. -const int kMaxInflightOperations = 5; -} - RecursiveOperationDelegate::RecursiveOperationDelegate( FileSystemContext* file_system_context) : file_system_context_(file_system_context), - inflight_operations_(0), canceled_(false), error_behavior_(FileSystemOperation::ERROR_BEHAVIOR_ABORT), failed_some_operations_(false) { @@ -42,7 +36,6 @@ void RecursiveOperationDelegate::StartRecursiveOperation( const StatusCallback& callback) { DCHECK(pending_directory_stack_.empty()); DCHECK(pending_files_.empty()); - DCHECK_EQ(0, inflight_operations_); error_behavior_ = error_behavior; callback_ = callback; @@ -51,7 +44,6 @@ void RecursiveOperationDelegate::StartRecursiveOperation( } void RecursiveOperationDelegate::TryProcessFile(const FileSystemURL& root) { - ++inflight_operations_; ProcessFile(root, base::Bind(&RecursiveOperationDelegate::DidTryProcessFile, AsWeakPtr(), root)); } @@ -68,9 +60,7 @@ void RecursiveOperationDelegate::DidTryProcessFile( base::File::Error error) { DCHECK(pending_directory_stack_.empty()); DCHECK(pending_files_.empty()); - DCHECK_EQ(1, inflight_operations_); - --inflight_operations_; if (canceled_ || error != base::File::FILE_ERROR_NOT_A_FILE) { Done(error); return; @@ -85,11 +75,9 @@ void RecursiveOperationDelegate::ProcessNextDirectory() { DCHECK(pending_files_.empty()); DCHECK(!pending_directory_stack_.empty()); DCHECK(!pending_directory_stack_.top().empty()); - DCHECK_EQ(0, inflight_operations_); const FileSystemURL& url = pending_directory_stack_.top().front(); - ++inflight_operations_; ProcessDirectory( url, base::Bind( @@ -101,9 +89,7 @@ void RecursiveOperationDelegate::DidProcessDirectory( DCHECK(pending_files_.empty()); DCHECK(!pending_directory_stack_.empty()); DCHECK(!pending_directory_stack_.top().empty()); - DCHECK_EQ(1, inflight_operations_); - --inflight_operations_; if (canceled_ || error != base::File::FILE_OK) { Done(error); return; @@ -123,7 +109,6 @@ void RecursiveOperationDelegate::DidReadDirectory( const FileEntryList& entries, bool has_more) { DCHECK(!pending_directory_stack_.empty()); - DCHECK_EQ(0, inflight_operations_); if (canceled_ || error != base::File::FILE_OK) { Done(error); @@ -151,7 +136,7 @@ void RecursiveOperationDelegate::DidReadDirectory( void RecursiveOperationDelegate::ProcessPendingFiles() { DCHECK(!pending_directory_stack_.empty()); - if ((pending_files_.empty() || canceled_) && inflight_operations_ == 0) { + if (pending_files_.empty() || canceled_) { ProcessSubDirectory(); return; } @@ -160,12 +145,10 @@ void RecursiveOperationDelegate::ProcessPendingFiles() { if (canceled_) return; - // Run ProcessFile in parallel (upto kMaxInflightOperations). + // Run ProcessFile. scoped_refptr<base::SingleThreadTaskRunner> current_task_runner = base::ThreadTaskRunnerHandle::Get(); - while (!pending_files_.empty() && - inflight_operations_ < kMaxInflightOperations) { - ++inflight_operations_; + if (!pending_files_.empty()) { current_task_runner->PostTask( FROM_HERE, base::Bind(&RecursiveOperationDelegate::ProcessFile, AsWeakPtr(), @@ -178,8 +161,6 @@ void RecursiveOperationDelegate::ProcessPendingFiles() { void RecursiveOperationDelegate::DidProcessFile(const FileSystemURL& url, base::File::Error error) { - --inflight_operations_; - if (error != base::File::FILE_OK) { if (error_behavior_ == FileSystemOperation::ERROR_BEHAVIOR_ABORT) { // If an error occurs, invoke Done immediately (even if there remain @@ -198,7 +179,6 @@ void RecursiveOperationDelegate::DidProcessFile(const FileSystemURL& url, void RecursiveOperationDelegate::ProcessSubDirectory() { DCHECK(pending_files_.empty()); DCHECK(!pending_directory_stack_.empty()); - DCHECK_EQ(0, inflight_operations_); if (canceled_) { Done(base::File::FILE_ERROR_ABORT); @@ -220,7 +200,6 @@ void RecursiveOperationDelegate::ProcessSubDirectory() { } DCHECK(!pending_directory_stack_.top().empty()); - ++inflight_operations_; PostProcessDirectory( pending_directory_stack_.top().front(), base::Bind(&RecursiveOperationDelegate::DidPostProcessDirectory, @@ -232,9 +211,7 @@ void RecursiveOperationDelegate::DidPostProcessDirectory( DCHECK(pending_files_.empty()); DCHECK(!pending_directory_stack_.empty()); DCHECK(!pending_directory_stack_.top().empty()); - DCHECK_EQ(1, inflight_operations_); - --inflight_operations_; pending_directory_stack_.top().pop(); if (canceled_ || error != base::File::FILE_OK) { Done(error); diff --git a/chromium/storage/browser/fileapi/recursive_operation_delegate.h b/chromium/storage/browser/fileapi/recursive_operation_delegate.h index 0a3efbf7b30..dc4362e1afd 100644 --- a/chromium/storage/browser/fileapi/recursive_operation_delegate.h +++ b/chromium/storage/browser/fileapi/recursive_operation_delegate.h @@ -74,7 +74,7 @@ class STORAGE_EXPORT RecursiveOperationDelegate // ProcessDirectory is called first for the directory. // Then the directory contents are read (to obtain its sub directories and // files in it). - // ProcessFile is called for found files. This may run in parallel. + // ProcessFile is called for found files. // The same step is recursively applied to each subdirectory. // After all files and subdirectories in a directory are processed, // PostProcessDirectory is called for the directory. @@ -91,11 +91,13 @@ class STORAGE_EXPORT RecursiveOperationDelegate // Then traverse order is: // ProcessFile(a_dir) (This should return File::FILE_NOT_A_FILE). // ProcessDirectory(a_dir). - // ProcessFile(b3_file), ProcessFile(b4_file). (in parallel). + // ProcessFile(b3_file). + // ProcessFile(b4_file). // ProcessDirectory(b1_dir). // ProcessFile(c2_file) // ProcessDirectory(c1_dir). - // ProcessFile(d1_file), ProcessFile(d2_file). (in parallel). + // ProcessFile(d1_file). + // ProcessFile(d2_file). // PostProcessDirectory(c1_dir) // PostProcessDirectory(b1_dir). // ProcessDirectory(b2_dir) @@ -146,7 +148,6 @@ class STORAGE_EXPORT RecursiveOperationDelegate std::stack<FileSystemURL> pending_directories_; std::stack<std::queue<FileSystemURL> > pending_directory_stack_; std::queue<FileSystemURL> pending_files_; - int inflight_operations_; bool canceled_; ErrorBehavior error_behavior_; bool failed_some_operations_; diff --git a/chromium/storage/browser/fileapi/sandbox_directory_database.cc b/chromium/storage/browser/fileapi/sandbox_directory_database.cc index 343f09f5c7a..a4e845aa61d 100644 --- a/chromium/storage/browser/fileapi/sandbox_directory_database.cc +++ b/chromium/storage/browser/fileapi/sandbox_directory_database.cc @@ -7,7 +7,9 @@ #include <math.h> #include <stddef.h> #include <stdint.h> + #include <algorithm> +#include <memory> #include <set> #include <stack> @@ -193,7 +195,8 @@ DatabaseCheckHelper::DatabaseCheckHelper( } bool DatabaseCheckHelper::IsDatabaseEmpty() { - scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); + std::unique_ptr<leveldb::Iterator> itr( + db_->NewIterator(leveldb::ReadOptions())); itr->SeekToFirst(); return !itr->Valid(); } @@ -204,7 +207,8 @@ bool DatabaseCheckHelper::ScanDatabase() { int64_t max_file_id = -1; std::set<FileId> file_ids; - scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); + std::unique_ptr<leveldb::Iterator> itr( + db_->NewIterator(leveldb::ReadOptions())); for (itr->SeekToFirst(); itr->Valid(); itr->Next()) { std::string key = itr->key().ToString(); if (base::StartsWith(key, kChildLookupPrefix, @@ -480,7 +484,8 @@ bool SandboxDirectoryDatabase::ListChildren( DCHECK(children); std::string child_key_prefix = GetChildListingKeyPrefix(parent_id); - scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); + std::unique_ptr<leveldb::Iterator> iter( + db_->NewIterator(leveldb::ReadOptions())); iter->Seek(child_key_prefix); children->clear(); while (iter->Valid() && base::StartsWith(iter->key().ToString(), @@ -844,11 +849,15 @@ void SandboxDirectoryDatabase::ReportInitStatus( bool SandboxDirectoryDatabase::StoreDefaultValues() { // Verify that this is a totally new database, and initialize it. - scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); - iter->SeekToFirst(); - if (iter->Valid()) { // DB was not empty--we shouldn't have been called. - LOG(ERROR) << "File system origin database is corrupt!"; - return false; + { + // Scope the iterator to ensure deleted before database is closed. + std::unique_ptr<leveldb::Iterator> iter( + db_->NewIterator(leveldb::ReadOptions())); + iter->SeekToFirst(); + if (iter->Valid()) { // DB was not empty--we shouldn't have been called. + LOG(ERROR) << "File system origin database is corrupt!"; + return false; + } } // This is always the first write into the database. If we ever add a // version number, it should go in this transaction too. diff --git a/chromium/storage/browser/fileapi/sandbox_directory_database.h b/chromium/storage/browser/fileapi/sandbox_directory_database.h index f63b68473cd..6df9f17cd91 100644 --- a/chromium/storage/browser/fileapi/sandbox_directory_database.h +++ b/chromium/storage/browser/fileapi/sandbox_directory_database.h @@ -7,13 +7,13 @@ #include <stdint.h> +#include <memory> #include <string> #include <vector> #include "base/files/file.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "storage/browser/storage_browser_export.h" @@ -123,12 +123,14 @@ class STORAGE_EXPORT SandboxDirectoryDatabase { bool AddFileInfoHelper( const FileInfo& info, FileId file_id, leveldb::WriteBatch* batch); bool RemoveFileInfoHelper(FileId file_id, leveldb::WriteBatch* batch); + // Close the database. Before this, all iterators associated with the database + // must be deleted. void HandleError(const tracked_objects::Location& from_here, const leveldb::Status& status); const base::FilePath filesystem_data_directory_; leveldb::Env* env_override_; - scoped_ptr<leveldb::DB> db_; + std::unique_ptr<leveldb::DB> db_; base::Time last_reported_time_; DISALLOW_COPY_AND_ASSIGN(SandboxDirectoryDatabase); }; diff --git a/chromium/storage/browser/fileapi/sandbox_file_stream_writer.cc b/chromium/storage/browser/fileapi/sandbox_file_stream_writer.cc index 09384ff46d3..3cca3d39f9e 100644 --- a/chromium/storage/browser/fileapi/sandbox_file_stream_writer.cc +++ b/chromium/storage/browser/fileapi/sandbox_file_stream_writer.cc @@ -7,6 +7,7 @@ #include <stdint.h> #include <limits> +#include <tuple> #include "base/files/file_util_proxy.h" #include "base/sequenced_task_runner.h" @@ -69,10 +70,9 @@ int SandboxFileStreamWriter::Write( if (local_file_writer_) return WriteInternal(buf, buf_len, callback); - net::CompletionCallback write_task = - base::Bind(&SandboxFileStreamWriter::DidInitializeForWrite, - weak_factory_.GetWeakPtr(), - make_scoped_refptr(buf), buf_len, callback); + net::CompletionCallback write_task = base::Bind( + &SandboxFileStreamWriter::DidInitializeForWrite, + weak_factory_.GetWeakPtr(), base::RetainedRef(buf), buf_len, callback); file_system_context_->operation_runner()->CreateSnapshotFile( url_, base::Bind(&SandboxFileStreamWriter::DidCreateSnapshotFile, weak_factory_.GetWeakPtr(), write_task)); @@ -227,7 +227,7 @@ void SandboxFileStreamWriter::DidWrite( if (overlapped < 0) overlapped = 0; observers_.Notify(&FileUpdateObserver::OnUpdate, - base::MakeTuple(url_, write_response - overlapped)); + std::make_tuple(url_, write_response - overlapped)); } total_bytes_written_ += write_response; diff --git a/chromium/storage/browser/fileapi/sandbox_file_stream_writer.h b/chromium/storage/browser/fileapi/sandbox_file_stream_writer.h index 91f8b0a03a7..f0dd10877f6 100644 --- a/chromium/storage/browser/fileapi/sandbox_file_stream_writer.h +++ b/chromium/storage/browser/fileapi/sandbox_file_stream_writer.h @@ -7,10 +7,11 @@ #include <stdint.h> +#include <memory> + #include "base/files/file.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/blob/shareable_file_reference.h" #include "storage/browser/fileapi/file_stream_writer.h" #include "storage/browser/fileapi/file_system_url.h" @@ -75,7 +76,7 @@ class STORAGE_EXPORT SandboxFileStreamWriter scoped_refptr<FileSystemContext> file_system_context_; FileSystemURL url_; int64_t initial_offset_; - scoped_ptr<FileStreamWriter> local_file_writer_; + std::unique_ptr<FileStreamWriter> local_file_writer_; net::CompletionCallback cancel_callback_; UpdateObserverList observers_; diff --git a/chromium/storage/browser/fileapi/sandbox_file_system_backend.cc b/chromium/storage/browser/fileapi/sandbox_file_system_backend.cc index 2b64193a5f2..a9c2e05b02f 100644 --- a/chromium/storage/browser/fileapi/sandbox_file_system_backend.cc +++ b/chromium/storage/browser/fileapi/sandbox_file_system_backend.cc @@ -5,6 +5,8 @@ #include "storage/browser/fileapi/sandbox_file_system_backend.h" #include <stdint.h> + +#include <memory> #include <utility> #include "base/bind.h" @@ -109,7 +111,7 @@ FileSystemOperation* SandboxFileSystemBackend::CreateFileSystemOperation( DCHECK(error_code); DCHECK(delegate_); - scoped_ptr<FileSystemOperationContext> operation_context = + std::unique_ptr<FileSystemOperationContext> operation_context = delegate_->CreateFileSystemOperationContext(url, context, error_code); if (!operation_context) return NULL; @@ -134,7 +136,7 @@ bool SandboxFileSystemBackend::HasInplaceCopyImplementation( return false; } -scoped_ptr<storage::FileStreamReader> +std::unique_ptr<storage::FileStreamReader> SandboxFileSystemBackend::CreateFileStreamReader( const FileSystemURL& url, int64_t offset, @@ -147,7 +149,7 @@ SandboxFileSystemBackend::CreateFileStreamReader( url, offset, expected_modification_time, context); } -scoped_ptr<storage::FileStreamWriter> +std::unique_ptr<storage::FileStreamWriter> SandboxFileSystemBackend::CreateFileStreamWriter( const FileSystemURL& url, int64_t offset, diff --git a/chromium/storage/browser/fileapi/sandbox_file_system_backend.h b/chromium/storage/browser/fileapi/sandbox_file_system_backend.h index 6ed885e2d93..f1035182fb5 100644 --- a/chromium/storage/browser/fileapi/sandbox_file_system_backend.h +++ b/chromium/storage/browser/fileapi/sandbox_file_system_backend.h @@ -7,6 +7,7 @@ #include <stdint.h> +#include <memory> #include <set> #include <string> @@ -14,7 +15,6 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/fileapi/file_system_backend.h" #include "storage/browser/fileapi/file_system_quota_util.h" #include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h" @@ -52,13 +52,13 @@ class STORAGE_EXPORT SandboxFileSystemBackend bool SupportsStreaming(const FileSystemURL& url) const override; bool HasInplaceCopyImplementation( storage::FileSystemType type) const override; - scoped_ptr<storage::FileStreamReader> CreateFileStreamReader( + std::unique_ptr<storage::FileStreamReader> CreateFileStreamReader( const FileSystemURL& url, int64_t offset, int64_t max_bytes_to_read, const base::Time& expected_modification_time, FileSystemContext* context) const override; - scoped_ptr<FileStreamWriter> CreateFileStreamWriter( + std::unique_ptr<FileStreamWriter> CreateFileStreamWriter( const FileSystemURL& url, int64_t offset, FileSystemContext* context) const override; diff --git a/chromium/storage/browser/fileapi/sandbox_file_system_backend_delegate.cc b/chromium/storage/browser/fileapi/sandbox_file_system_backend_delegate.cc index 5e3138f1019..f4714c78b1d 100644 --- a/chromium/storage/browser/fileapi/sandbox_file_system_backend_delegate.cc +++ b/chromium/storage/browser/fileapi/sandbox_file_system_backend_delegate.cc @@ -7,6 +7,7 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <vector> #include "base/command_line.h" @@ -15,7 +16,7 @@ #include "base/metrics/histogram.h" #include "base/stl_util.h" #include "base/task_runner_util.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "storage/browser/fileapi/async_file_util_adapter.h" #include "storage/browser/fileapi/file_stream_reader.h" #include "storage/browser/fileapi/file_system_context.h" @@ -106,7 +107,7 @@ class ObfuscatedOriginEnumerator } private: - scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_; + std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_; }; void OpenFileSystemOnFileTaskRunner( @@ -192,7 +193,7 @@ SandboxFileSystemBackendDelegate::SandboxFileSystemBackendDelegate( obfuscated_file_util(), usage_cache())), quota_reservation_manager_(new QuotaReservationManager( - scoped_ptr<QuotaReservationManager::QuotaBackend>( + std::unique_ptr<QuotaReservationManager::QuotaBackend>( new QuotaBackendImpl(file_task_runner_.get(), obfuscated_file_util(), usage_cache(), @@ -274,21 +275,21 @@ void SandboxFileSystemBackendDelegate::OpenFileSystem( is_filesystem_opened_ = true; } -scoped_ptr<FileSystemOperationContext> +std::unique_ptr<FileSystemOperationContext> SandboxFileSystemBackendDelegate::CreateFileSystemOperationContext( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const { if (!IsAccessValid(url)) { *error_code = base::File::FILE_ERROR_SECURITY; - return scoped_ptr<FileSystemOperationContext>(); + return std::unique_ptr<FileSystemOperationContext>(); } const UpdateObserverList* update_observers = GetUpdateObservers(url.type()); const ChangeObserverList* change_observers = GetChangeObservers(url.type()); DCHECK(update_observers); - scoped_ptr<FileSystemOperationContext> operation_context( + std::unique_ptr<FileSystemOperationContext> operation_context( new FileSystemOperationContext(context)); operation_context->set_update_observers(*update_observers); operation_context->set_change_observers( @@ -297,30 +298,30 @@ SandboxFileSystemBackendDelegate::CreateFileSystemOperationContext( return operation_context; } -scoped_ptr<storage::FileStreamReader> +std::unique_ptr<storage::FileStreamReader> SandboxFileSystemBackendDelegate::CreateFileStreamReader( const FileSystemURL& url, int64_t offset, const base::Time& expected_modification_time, FileSystemContext* context) const { if (!IsAccessValid(url)) - return scoped_ptr<storage::FileStreamReader>(); - return scoped_ptr<storage::FileStreamReader>( + return std::unique_ptr<storage::FileStreamReader>(); + return std::unique_ptr<storage::FileStreamReader>( storage::FileStreamReader::CreateForFileSystemFile( context, url, offset, expected_modification_time)); } -scoped_ptr<FileStreamWriter> +std::unique_ptr<FileStreamWriter> SandboxFileSystemBackendDelegate::CreateFileStreamWriter( const FileSystemURL& url, int64_t offset, FileSystemContext* context, FileSystemType type) const { if (!IsAccessValid(url)) - return scoped_ptr<FileStreamWriter>(); + return std::unique_ptr<FileStreamWriter>(); const UpdateObserverList* observers = GetUpdateObservers(type); DCHECK(observers); - return scoped_ptr<FileStreamWriter>( + return std::unique_ptr<FileStreamWriter>( new SandboxFileStreamWriter(context, url, offset, *observers)); } @@ -352,7 +353,7 @@ void SandboxFileSystemBackendDelegate::GetOriginsForTypeOnFileTaskRunner( FileSystemType type, std::set<GURL>* origins) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(origins); - scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); + std::unique_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); GURL origin; while (!(origin = enumerator->Next()).is_empty()) { if (enumerator->HasFileSystemType(type)) @@ -375,7 +376,7 @@ void SandboxFileSystemBackendDelegate::GetOriginsForHostOnFileTaskRunner( std::set<GURL>* origins) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(origins); - scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); + std::unique_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); GURL origin; while (!(origin = enumerator->Next()).is_empty()) { if (host == net::GetHostOrSpecFromURL(origin) && @@ -600,9 +601,9 @@ int64_t SandboxFileSystemBackendDelegate::RecalculateUsage( FileSystemOperationContext operation_context(context); FileSystemURL url = context->CreateCrackedFileSystemURL( origin, type, base::FilePath()); - scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( - obfuscated_file_util()->CreateFileEnumerator( - &operation_context, url, true)); + std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( + obfuscated_file_util()->CreateFileEnumerator(&operation_context, url, + true)); base::FilePath file_path_each; int64_t usage = 0; diff --git a/chromium/storage/browser/fileapi/sandbox_file_system_backend_delegate.h b/chromium/storage/browser/fileapi/sandbox_file_system_backend_delegate.h index b5c731e2a96..1a1696f4f29 100644 --- a/chromium/storage/browser/fileapi/sandbox_file_system_backend_delegate.h +++ b/chromium/storage/browser/fileapi/sandbox_file_system_backend_delegate.h @@ -8,6 +8,7 @@ #include <stdint.h> #include <map> +#include <memory> #include <set> #include <string> #include <utility> @@ -15,7 +16,6 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "base/time/time.h" @@ -113,16 +113,16 @@ class STORAGE_EXPORT SandboxFileSystemBackendDelegate OpenFileSystemMode mode, const OpenFileSystemCallback& callback, const GURL& root_url); - scoped_ptr<FileSystemOperationContext> CreateFileSystemOperationContext( + std::unique_ptr<FileSystemOperationContext> CreateFileSystemOperationContext( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const; - scoped_ptr<storage::FileStreamReader> CreateFileStreamReader( + std::unique_ptr<storage::FileStreamReader> CreateFileStreamReader( const FileSystemURL& url, int64_t offset, const base::Time& expected_modification_time, FileSystemContext* context) const; - scoped_ptr<FileStreamWriter> CreateFileStreamWriter( + std::unique_ptr<FileStreamWriter> CreateFileStreamWriter( const FileSystemURL& url, int64_t offset, FileSystemContext* context, @@ -234,10 +234,10 @@ class STORAGE_EXPORT SandboxFileSystemBackendDelegate scoped_refptr<base::SequencedTaskRunner> file_task_runner_; - scoped_ptr<AsyncFileUtil> sandbox_file_util_; - scoped_ptr<FileSystemUsageCache> file_system_usage_cache_; - scoped_ptr<SandboxQuotaObserver> quota_observer_; - scoped_ptr<QuotaReservationManager> quota_reservation_manager_; + std::unique_ptr<AsyncFileUtil> sandbox_file_util_; + std::unique_ptr<FileSystemUsageCache> file_system_usage_cache_; + std::unique_ptr<SandboxQuotaObserver> quota_observer_; + std::unique_ptr<QuotaReservationManager> quota_reservation_manager_; scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_; diff --git a/chromium/storage/browser/fileapi/sandbox_origin_database.cc b/chromium/storage/browser/fileapi/sandbox_origin_database.cc index 85424a2351c..992c5cfbe6b 100644 --- a/chromium/storage/browser/fileapi/sandbox_origin_database.cc +++ b/chromium/storage/browser/fileapi/sandbox_origin_database.cc @@ -6,6 +6,7 @@ #include <stdint.h> +#include <memory> #include <set> #include <utility> @@ -289,7 +290,8 @@ bool SandboxOriginDatabase::ListAllOrigins( origins->clear(); return false; } - scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); + std::unique_ptr<leveldb::Iterator> iter( + db_->NewIterator(leveldb::ReadOptions())); std::string origin_key_prefix = OriginToOriginKey(std::string()); iter->Seek(origin_key_prefix); origins->clear(); @@ -331,16 +333,19 @@ bool SandboxOriginDatabase::GetLastPathNumber(int* number) { return false; } // Verify that this is a totally new database, and initialize it. - scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); - iter->SeekToFirst(); - if (iter->Valid()) { // DB was not empty, but had no last path number! - LOG(ERROR) << "File system origin database is corrupt!"; - return false; + { + // Scope the iterator to ensure it is deleted before database is closed. + std::unique_ptr<leveldb::Iterator> iter( + db_->NewIterator(leveldb::ReadOptions())); + iter->SeekToFirst(); + if (iter->Valid()) { // DB was not empty, but had no last path number! + LOG(ERROR) << "File system origin database is corrupt!"; + return false; + } } // This is always the first write into the database. If we ever add a // version number, they should go in in a single transaction. - status = - db_->Put(leveldb::WriteOptions(), LastPathKey(), std::string("-1")); + status = db_->Put(leveldb::WriteOptions(), LastPathKey(), std::string("-1")); if (!status.ok()) { HandleError(FROM_HERE, status); return false; diff --git a/chromium/storage/browser/fileapi/sandbox_origin_database.h b/chromium/storage/browser/fileapi/sandbox_origin_database.h index 0562385ebd6..84fda561a84 100644 --- a/chromium/storage/browser/fileapi/sandbox_origin_database.h +++ b/chromium/storage/browser/fileapi/sandbox_origin_database.h @@ -5,11 +5,11 @@ #ifndef STORAGE_BROWSER_FILEAPI_SANDBOX_ORIGIN_DATABASE_H_ #define STORAGE_BROWSER_FILEAPI_SANDBOX_ORIGIN_DATABASE_H_ +#include <memory> #include <string> #include <vector> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "storage/browser/fileapi/sandbox_origin_database_interface.h" @@ -61,6 +61,8 @@ class STORAGE_EXPORT SandboxOriginDatabase bool Init(InitOption init_option, RecoveryOption recovery_option); bool RepairDatabase(const std::string& db_path); + // Close the database. Before this, all iterators associated with the database + // must be deleted. void HandleError(const tracked_objects::Location& from_here, const leveldb::Status& status); void ReportInitStatus(const leveldb::Status& status); @@ -68,7 +70,7 @@ class STORAGE_EXPORT SandboxOriginDatabase base::FilePath file_system_directory_; leveldb::Env* env_override_; - scoped_ptr<leveldb::DB> db_; + std::unique_ptr<leveldb::DB> db_; base::Time last_reported_time_; DISALLOW_COPY_AND_ASSIGN(SandboxOriginDatabase); }; diff --git a/chromium/storage/browser/fileapi/sandbox_prioritized_origin_database.h b/chromium/storage/browser/fileapi/sandbox_prioritized_origin_database.h index 78435656ef8..053d61e91f1 100644 --- a/chromium/storage/browser/fileapi/sandbox_prioritized_origin_database.h +++ b/chromium/storage/browser/fileapi/sandbox_prioritized_origin_database.h @@ -5,12 +5,12 @@ #ifndef STORAGE_BROWSER_FILEAPI_SANDBOX_PRIORITIZED_ORIGIN_DATABASE_H_ #define STORAGE_BROWSER_FILEAPI_SANDBOX_PRIORITIZED_ORIGIN_DATABASE_H_ +#include <memory> #include <string> #include <vector> #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/fileapi/sandbox_origin_database_interface.h" namespace leveldb { @@ -66,8 +66,8 @@ class STORAGE_EXPORT SandboxPrioritizedOriginDatabase const base::FilePath file_system_directory_; leveldb::Env* env_override_; const base::FilePath primary_origin_file_; - scoped_ptr<SandboxOriginDatabase> origin_database_; - scoped_ptr<SandboxIsolatedOriginDatabase> primary_origin_database_; + std::unique_ptr<SandboxOriginDatabase> origin_database_; + std::unique_ptr<SandboxIsolatedOriginDatabase> primary_origin_database_; DISALLOW_COPY_AND_ASSIGN(SandboxPrioritizedOriginDatabase); }; diff --git a/chromium/storage/browser/fileapi/sandbox_quota_observer.h b/chromium/storage/browser/fileapi/sandbox_quota_observer.h index 769c062f14a..729bf0af70e 100644 --- a/chromium/storage/browser/fileapi/sandbox_quota_observer.h +++ b/chromium/storage/browser/fileapi/sandbox_quota_observer.h @@ -8,12 +8,12 @@ #include <stdint.h> #include <map> +#include <memory> #include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "storage/browser/fileapi/file_observers.h" #include "storage/browser/fileapi/file_system_url.h" @@ -74,7 +74,7 @@ class SandboxQuotaObserver FileSystemUsageCache* file_system_usage_cache_; PendingUpdateNotificationMap pending_update_notification_; - scoped_ptr<TimedTaskHelper> delayed_cache_update_helper_; + std::unique_ptr<TimedTaskHelper> delayed_cache_update_helper_; DISALLOW_COPY_AND_ASSIGN(SandboxQuotaObserver); }; diff --git a/chromium/storage/browser/fileapi/task_runner_bound_observer_list.h b/chromium/storage/browser/fileapi/task_runner_bound_observer_list.h index bbe91f777fe..eae9ddf18d4 100644 --- a/chromium/storage/browser/fileapi/task_runner_bound_observer_list.h +++ b/chromium/storage/browser/fileapi/task_runner_bound_observer_list.h @@ -11,13 +11,14 @@ #include "base/memory/ref_counted.h" #include "base/sequenced_task_runner.h" #include "base/threading/thread.h" +#include "base/tuple.h" namespace storage { // A wrapper for dispatching method. template <class T, class Method, class Params> void NotifyWrapper(T obj, Method m, const Params& p) { - base::DispatchToMethod(base::internal::UnwrapTraits<T>::Unwrap(obj), m, p); + base::DispatchToMethod(obj, m, p); } // An observer list helper to notify on a given task runner. @@ -69,7 +70,7 @@ class TaskRunnerBoundObserverList { for (typename ObserversListMap::const_iterator it = observers_.begin(); it != observers_.end(); ++it) { if (!it->second.get() || it->second->RunsTasksOnCurrentThread()) { - base::DispatchToMethod(UnwrapTraits::Unwrap(it->first), method, params); + base::DispatchToMethod(it->first, method, params); continue; } it->second->PostTask( @@ -80,8 +81,6 @@ class TaskRunnerBoundObserverList { } private: - typedef base::internal::UnwrapTraits<ObserverStoreType> UnwrapTraits; - ObserversListMap observers_; }; diff --git a/chromium/storage/browser/fileapi/timed_task_helper.cc b/chromium/storage/browser/fileapi/timed_task_helper.cc index 69635d00bde..17adbd763a2 100644 --- a/chromium/storage/browser/fileapi/timed_task_helper.cc +++ b/chromium/storage/browser/fileapi/timed_task_helper.cc @@ -4,10 +4,12 @@ #include "storage/browser/fileapi/timed_task_helper.h" +#include <memory> #include <utility> #include "base/bind.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" namespace storage { @@ -58,18 +60,18 @@ void TimedTaskHelper::Reset() { // Initialize the tracker for the first time. tracker_ = new Tracker(this); - PostDelayedTask(make_scoped_ptr(tracker_), delay_); + PostDelayedTask(base::WrapUnique(tracker_), delay_); } // static -void TimedTaskHelper::Fired(scoped_ptr<Tracker> tracker) { +void TimedTaskHelper::Fired(std::unique_ptr<Tracker> tracker) { if (!tracker->timer) return; TimedTaskHelper* timer = tracker->timer; timer->OnFired(std::move(tracker)); } -void TimedTaskHelper::OnFired(scoped_ptr<Tracker> tracker) { +void TimedTaskHelper::OnFired(std::unique_ptr<Tracker> tracker) { DCHECK(task_runner_->RunsTasksOnCurrentThread()); base::TimeTicks now = base::TimeTicks::Now(); if (desired_run_time_ > now) { @@ -82,7 +84,7 @@ void TimedTaskHelper::OnFired(scoped_ptr<Tracker> tracker) { task.Run(); } -void TimedTaskHelper::PostDelayedTask(scoped_ptr<Tracker> tracker, +void TimedTaskHelper::PostDelayedTask(std::unique_ptr<Tracker> tracker, base::TimeDelta delay) { task_runner_->PostDelayedTask( posted_from_, diff --git a/chromium/storage/browser/fileapi/timed_task_helper.h b/chromium/storage/browser/fileapi/timed_task_helper.h index fb0d5f26144..09a6137fd63 100644 --- a/chromium/storage/browser/fileapi/timed_task_helper.h +++ b/chromium/storage/browser/fileapi/timed_task_helper.h @@ -5,11 +5,12 @@ #ifndef STORAGE_BROWSER_FILEAPI_TIMED_TASK_HELPER_H_ #define STORAGE_BROWSER_FILEAPI_TIMED_TASK_HELPER_H_ +#include <memory> + #include "base/callback.h" #include "base/location.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "storage/browser/storage_browser_export.h" @@ -36,10 +37,10 @@ class STORAGE_EXPORT TimedTaskHelper { private: struct Tracker; - static void Fired(scoped_ptr<Tracker> tracker); + static void Fired(std::unique_ptr<Tracker> tracker); - void OnFired(scoped_ptr<Tracker> tracker); - void PostDelayedTask(scoped_ptr<Tracker> tracker, base::TimeDelta delay); + void OnFired(std::unique_ptr<Tracker> tracker); + void PostDelayedTask(std::unique_ptr<Tracker> tracker, base::TimeDelta delay); scoped_refptr<base::SequencedTaskRunner> task_runner_; tracked_objects::Location posted_from_; diff --git a/chromium/storage/browser/fileapi/transient_file_util.h b/chromium/storage/browser/fileapi/transient_file_util.h index d3e3da7bde2..68440e04704 100644 --- a/chromium/storage/browser/fileapi/transient_file_util.h +++ b/chromium/storage/browser/fileapi/transient_file_util.h @@ -5,8 +5,9 @@ #ifndef STORAGE_BROWSER_FILEAPI_TRANSIENT_FILE_UTIL_H_ #define STORAGE_BROWSER_FILEAPI_TRANSIENT_FILE_UTIL_H_ +#include <memory> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "storage/browser/fileapi/local_file_util.h" #include "storage/browser/storage_browser_export.h" diff --git a/chromium/storage/browser/quota/client_usage_tracker.cc b/chromium/storage/browser/quota/client_usage_tracker.cc index e0a901c76a1..477fdb5e932 100644 --- a/chromium/storage/browser/quota/client_usage_tracker.cc +++ b/chromium/storage/browser/quota/client_usage_tracker.cc @@ -8,7 +8,7 @@ #include "base/bind.h" #include "base/stl_util.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "storage/browser/quota/storage_monitor.h" #include "storage/browser/quota/storage_observer.h" diff --git a/chromium/storage/browser/quota/client_usage_tracker.h b/chromium/storage/browser/quota/client_usage_tracker.h index 359b6807927..5b5a84b201b 100644 --- a/chromium/storage/browser/quota/client_usage_tracker.h +++ b/chromium/storage/browser/quota/client_usage_tracker.h @@ -8,13 +8,13 @@ #include <stdint.h> #include <map> +#include <memory> #include <set> #include <string> #include <vector> #include "base/callback.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/threading/non_thread_safe.h" #include "storage/browser/quota/quota_callbacks.h" #include "storage/browser/quota/quota_client.h" diff --git a/chromium/storage/browser/quota/quota_callbacks.h b/chromium/storage/browser/quota/quota_callbacks.h index 270e14f435d..6b9680287ef 100644 --- a/chromium/storage/browser/quota/quota_callbacks.h +++ b/chromium/storage/browser/quota/quota_callbacks.h @@ -10,6 +10,7 @@ #include <map> #include <set> +#include <utility> #include <vector> #include "base/callback.h" @@ -51,12 +52,11 @@ class CallbackQueue { } // Runs the callbacks added to the queue and clears the queue. - void Run( - typename base::internal::CallbackParamTraits<Args>::ForwardType... args) { + void Run(Args... args) { std::vector<CallbackType> callbacks; callbacks.swap(callbacks_); for (const auto& callback : callbacks) - callback.Run(base::internal::CallbackForward(args)...); + callback.Run(args...); } void Swap(CallbackQueue<CallbackType, Args...>* other) { @@ -97,15 +97,14 @@ class CallbackQueueMap { // Runs the callbacks added for the given |key| and clears the key // from the map. - void Run( - const Key& key, - typename base::internal::CallbackParamTraits<Args>::ForwardType... args) { + template <typename... RunArgs> + void Run(const Key& key, RunArgs&&... args) { if (!this->HasCallbacks(key)) return; CallbackQueueType queue; queue.Swap(&callback_map_[key]); callback_map_.erase(key); - queue.Run(base::internal::CallbackForward(args)...); + queue.Run(std::forward<RunArgs>(args)...); } private: diff --git a/chromium/storage/browser/quota/quota_database.h b/chromium/storage/browser/quota/quota_database.h index bcda3692203..4eae12d92c3 100644 --- a/chromium/storage/browser/quota/quota_database.h +++ b/chromium/storage/browser/quota/quota_database.h @@ -8,13 +8,13 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <set> #include <string> #include "base/callback.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "storage/browser/storage_browser_export.h" @@ -188,8 +188,8 @@ class STORAGE_EXPORT QuotaDatabase { base::FilePath db_file_path_; - scoped_ptr<sql::Connection> db_; - scoped_ptr<sql::MetaTable> meta_table_; + std::unique_ptr<sql::Connection> db_; + std::unique_ptr<sql::MetaTable> meta_table_; bool is_recreating_; bool is_disabled_; diff --git a/chromium/storage/browser/quota/quota_manager.cc b/chromium/storage/browser/quota/quota_manager.cc index b6ba9ad34ef..26e469a9264 100644 --- a/chromium/storage/browser/quota/quota_manager.cc +++ b/chromium/storage/browser/quota/quota_manager.cc @@ -6,9 +6,11 @@ #include <stddef.h> #include <stdint.h> + #include <algorithm> #include <functional> #include <limits> +#include <memory> #include <utility> #include "base/bind.h" @@ -25,7 +27,7 @@ #include "base/task_runner_util.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "storage/browser/quota/client_usage_tracker.h" #include "storage/browser/quota/quota_manager_proxy.h" #include "storage/browser/quota/quota_temporary_storage_evictor.h" @@ -886,9 +888,8 @@ QuotaManager::QuotaManager( is_getting_eviction_origin_(false), temporary_quota_initialized_(false), temporary_quota_override_(-1), - desired_available_space_(-1), special_storage_policy_(special_storage_policy), - get_disk_space_fn_(&QuotaManager::CallSystemGetAmountOfFreeDiskSpace), + get_volume_info_fn_(&QuotaManager::GetVolumeInfo), storage_monitor_(new StorageMonitor(this)), weak_factory_(this) {} @@ -922,7 +923,6 @@ void QuotaManager::GetUsageAndQuotaForWebApps( UsageAndQuotaCallbackDispatcher* dispatcher = new UsageAndQuotaCallbackDispatcher(this); - UsageAndQuota usage_and_quota; if (unlimited) { dispatcher->set_quota(kNoLimit); } else { @@ -1003,7 +1003,7 @@ void QuotaManager::SetUsageCacheEnabled(QuotaClient::ID client_id, } void QuotaManager::SetTemporaryStorageEvictionPolicy( - scoped_ptr<QuotaEvictionPolicy> policy) { + std::unique_ptr<QuotaEvictionPolicy> policy) { temporary_storage_eviction_policy_ = std::move(policy); } @@ -1036,11 +1036,13 @@ void QuotaManager::GetAvailableSpace(const AvailableSpaceCallback& callback) { // crbug.com/349708 TRACE_EVENT0("io", "QuotaManager::GetAvailableSpace"); - PostTaskAndReplyWithResult(db_thread_.get(), - FROM_HERE, - base::Bind(get_disk_space_fn_, profile_path_), - base::Bind(&QuotaManager::DidGetAvailableSpace, - weak_factory_.GetWeakPtr())); + PostTaskAndReplyWithResult( + db_thread_.get(), + FROM_HERE, + base::Bind(&QuotaManager::CallGetAmountOfFreeDiskSpace, + get_volume_info_fn_, profile_path_), + base::Bind(&QuotaManager::DidGetAvailableSpace, + weak_factory_.GetWeakPtr())); } void QuotaManager::GetTemporaryGlobalQuota(const QuotaCallback& callback) { @@ -1282,8 +1284,8 @@ void QuotaManager::RemoveStorageObserverForFilter( QuotaManager::~QuotaManager() { proxy_->manager_ = NULL; - std::for_each(clients_.begin(), clients_.end(), - std::mem_fun(&QuotaClient::OnQuotaManagerDestroyed)); + for (auto* client : clients_) + client->OnQuotaManagerDestroyed(); if (database_) db_thread_->DeleteSoon(FROM_HERE, database_.release()); } @@ -1626,6 +1628,32 @@ void QuotaManager::GetUsageAndQuotaForEviction( dispatcher->WaitForResults(callback); } +void QuotaManager::AsyncGetVolumeInfo( + const VolumeInfoCallback& callback) { + DCHECK(io_thread_->BelongsToCurrentThread()); + uint64_t* available_space = new uint64_t(0); + uint64_t* total_space = new uint64_t(0); + PostTaskAndReplyWithResult( + db_thread_.get(), + FROM_HERE, + base::Bind(get_volume_info_fn_, + profile_path_, + base::Unretained(available_space), + base::Unretained(total_space)), + base::Bind(&QuotaManager::DidGetVolumeInfo, + weak_factory_.GetWeakPtr(), + callback, + base::Owned(available_space), + base::Owned(total_space))); +} + +void QuotaManager::DidGetVolumeInfo( + const VolumeInfoCallback& callback, + uint64_t* available_space, uint64_t* total_space, bool success) { + DCHECK(io_thread_->BelongsToCurrentThread()); + callback.Run(success, *available_space, *total_space); +} + void QuotaManager::GetLRUOrigin(StorageType type, const GetOriginCallback& callback) { LazyInitialize(); @@ -1642,7 +1670,8 @@ void QuotaManager::GetLRUOrigin(StorageType type, PostTaskAndReplyWithResultForDBThread( FROM_HERE, base::Bind(&GetLRUOriginOnDBThread, type, GetEvictionOriginExceptions(std::set<GURL>()), - special_storage_policy_, base::Unretained(url)), + base::RetainedRef(special_storage_policy_), + base::Unretained(url)), base::Bind(&QuotaManager::DidGetLRUOrigin, weak_factory_.GetWeakPtr(), base::Owned(url))); } @@ -1769,8 +1798,9 @@ void QuotaManager::PostTaskAndReplyWithResultForDBThread( reply); } -//static -int64_t QuotaManager::CallSystemGetAmountOfFreeDiskSpace( +// static +int64_t QuotaManager::CallGetAmountOfFreeDiskSpace( + GetVolumeInfoFn get_volume_info_fn, const base::FilePath& profile_path) { // crbug.com/349708 TRACE_EVENT0("io", "CallSystemGetAmountOfFreeDiskSpace"); @@ -1779,7 +1809,7 @@ int64_t QuotaManager::CallSystemGetAmountOfFreeDiskSpace( return 0; } uint64_t available, total; - if (!QuotaManager::GetVolumeInfo(profile_path, &available, &total)) { + if (!get_volume_info_fn(profile_path, &available, &total)) { return 0; } UMA_HISTOGRAM_MBYTES("Quota.AvailableDiskSpace", available); diff --git a/chromium/storage/browser/quota/quota_manager.h b/chromium/storage/browser/quota/quota_manager.h index 16e35277e1b..cd691db9491 100644 --- a/chromium/storage/browser/quota/quota_manager.h +++ b/chromium/storage/browser/quota/quota_manager.h @@ -10,6 +10,7 @@ #include <deque> #include <list> #include <map> +#include <memory> #include <set> #include <string> #include <utility> @@ -19,7 +20,6 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner_helpers.h" #include "storage/browser/quota/quota_callbacks.h" @@ -93,10 +93,11 @@ class STORAGE_EXPORT QuotaEvictionPolicy { // An interface called by QuotaTemporaryStorageEvictor. class STORAGE_EXPORT QuotaEvictionHandler { public: - typedef StatusCallback EvictOriginDataCallback; - typedef base::Callback<void(QuotaStatusCode status, - const UsageAndQuota& usage_and_quota)> - UsageAndQuotaCallback; + using EvictOriginDataCallback = StatusCallback; + using UsageAndQuotaCallback = base::Callback< + void(QuotaStatusCode status, const UsageAndQuota& usage_and_quota)>; + using VolumeInfoCallback = base::Callback< + void(bool success, uint64_t available_space, uint64_t total_space)>; // Returns next origin to evict. It might return an empty GURL when there are // no evictable origins. @@ -110,6 +111,7 @@ class STORAGE_EXPORT QuotaEvictionHandler { StorageType type, const EvictOriginDataCallback& callback) = 0; + virtual void AsyncGetVolumeInfo(const VolumeInfoCallback& callback) = 0; virtual void GetUsageAndQuotaForEviction( const UsageAndQuotaCallback& callback) = 0; @@ -202,7 +204,7 @@ class STORAGE_EXPORT QuotaManager // Set the eviction policy to use when choosing an origin to evict. void SetTemporaryStorageEvictionPolicy( - scoped_ptr<QuotaEvictionPolicy> policy); + std::unique_ptr<QuotaEvictionPolicy> policy); // DeleteOriginData and DeleteHostData (surprisingly enough) delete data of a // particular StorageType associated with either a specific origin or set of @@ -316,9 +318,10 @@ class STORAGE_EXPORT QuotaManager typedef std::vector<QuotaTableEntry> QuotaTableEntries; typedef std::vector<OriginInfoTableEntry> OriginInfoTableEntries; - // Function pointer type used to store the function which returns the - // available disk space for the disk containing the given FilePath. - typedef int64_t (*GetAvailableDiskSpaceFn)(const base::FilePath&); + // Function pointer type used to store the function which returns + // information about the volume containing the given FilePath. + using GetVolumeInfoFn = bool(*)(const base::FilePath&, + uint64_t* available, uint64_t* total); typedef base::Callback<void(const QuotaTableEntries&)> DumpQuotaTableCallback; @@ -410,6 +413,11 @@ class STORAGE_EXPORT QuotaManager const EvictOriginDataCallback& callback) override; void GetUsageAndQuotaForEviction( const UsageAndQuotaCallback& callback) override; + void AsyncGetVolumeInfo(const VolumeInfoCallback& callback) override; + + void DidGetVolumeInfo( + const VolumeInfoCallback& callback, + uint64_t* available_space, uint64_t* total_space, bool success); void GetLRUOrigin(StorageType type, const GetOriginCallback& callback); @@ -442,7 +450,8 @@ class STORAGE_EXPORT QuotaManager const base::Callback<bool(QuotaDatabase*)>& task, const base::Callback<void(bool)>& reply); - static int64_t CallSystemGetAmountOfFreeDiskSpace( + static int64_t CallGetAmountOfFreeDiskSpace( + GetVolumeInfoFn get_vol_info_fn, const base::FilePath& profile_path); static bool GetVolumeInfo(const base::FilePath& path, uint64_t* available_space, @@ -456,22 +465,22 @@ class STORAGE_EXPORT QuotaManager bool eviction_disabled_; scoped_refptr<base::SingleThreadTaskRunner> io_thread_; scoped_refptr<base::SequencedTaskRunner> db_thread_; - mutable scoped_ptr<QuotaDatabase> database_; + mutable std::unique_ptr<QuotaDatabase> database_; GetOriginCallback lru_origin_callback_; std::set<GURL> access_notified_origins_; QuotaClientList clients_; - scoped_ptr<UsageTracker> temporary_usage_tracker_; - scoped_ptr<UsageTracker> persistent_usage_tracker_; - scoped_ptr<UsageTracker> syncable_usage_tracker_; + std::unique_ptr<UsageTracker> temporary_usage_tracker_; + std::unique_ptr<UsageTracker> persistent_usage_tracker_; + std::unique_ptr<UsageTracker> syncable_usage_tracker_; // TODO(michaeln): Need a way to clear the cache, drop and // reinstantiate the trackers when they're not handling requests. - scoped_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_; + std::unique_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_; EvictionContext eviction_context_; - scoped_ptr<QuotaEvictionPolicy> temporary_storage_eviction_policy_; + std::unique_ptr<QuotaEvictionPolicy> temporary_storage_eviction_policy_; bool is_getting_eviction_origin_; ClosureQueue db_initialization_callbacks_; @@ -480,7 +489,6 @@ class STORAGE_EXPORT QuotaManager bool temporary_quota_initialized_; int64_t temporary_quota_override_; - int64_t desired_available_space_; // Map from origin to count. @@ -492,12 +500,12 @@ class STORAGE_EXPORT QuotaManager base::RepeatingTimer histogram_timer_; - // Pointer to the function used to get the available disk space. This is - // overwritten by QuotaManagerTest in order to attain a deterministic reported - // value. The default value points to base::SysInfo::AmountOfFreeDiskSpace. - GetAvailableDiskSpaceFn get_disk_space_fn_; + // Pointer to the function used to get volume information. This is + // overwritten by QuotaManagerTest in order to attain deterministic reported + // values. The default value points to QuotaManager::GetVolumeInfo. + GetVolumeInfoFn get_volume_info_fn_; - scoped_ptr<StorageMonitor> storage_monitor_; + std::unique_ptr<StorageMonitor> storage_monitor_; base::WeakPtrFactory<QuotaManager> weak_factory_; diff --git a/chromium/storage/browser/quota/quota_manager_proxy.cc b/chromium/storage/browser/quota/quota_manager_proxy.cc index 2efd22c80fb..0c1ad0a9467 100644 --- a/chromium/storage/browser/quota/quota_manager_proxy.cc +++ b/chromium/storage/browser/quota/quota_manager_proxy.cc @@ -26,10 +26,9 @@ void DidGetUsageAndQuota( int64_t quota) { if (!original_task_runner->RunsTasksOnCurrentThread()) { original_task_runner->PostTask( - FROM_HERE, - base::Bind(&DidGetUsageAndQuota, - make_scoped_refptr(original_task_runner), - callback, status, usage, quota)); + FROM_HERE, base::Bind(&DidGetUsageAndQuota, + base::RetainedRef(original_task_runner), callback, + status, usage, quota)); return; } @@ -134,10 +133,9 @@ void QuotaManagerProxy::GetUsageAndQuota( const GetUsageAndQuotaCallback& callback) { if (!io_thread_->BelongsToCurrentThread()) { io_thread_->PostTask( - FROM_HERE, - base::Bind(&QuotaManagerProxy::GetUsageAndQuota, this, - make_scoped_refptr(original_task_runner), - origin, type, callback)); + FROM_HERE, base::Bind(&QuotaManagerProxy::GetUsageAndQuota, this, + base::RetainedRef(original_task_runner), origin, + type, callback)); return; } if (!manager_) { @@ -150,8 +148,8 @@ void QuotaManagerProxy::GetUsageAndQuota( manager_->GetUsageAndQuota( origin, type, - base::Bind(&DidGetUsageAndQuota, - make_scoped_refptr(original_task_runner), callback)); + base::Bind(&DidGetUsageAndQuota, base::RetainedRef(original_task_runner), + callback)); } QuotaManager* QuotaManagerProxy::quota_manager() const { diff --git a/chromium/storage/browser/quota/quota_manager_proxy.h b/chromium/storage/browser/quota/quota_manager_proxy.h index 787a10b2c9f..19a1f89de33 100644 --- a/chromium/storage/browser/quota/quota_manager_proxy.h +++ b/chromium/storage/browser/quota/quota_manager_proxy.h @@ -7,11 +7,12 @@ #include <stdint.h> +#include <memory> + #include "base/callback.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner_helpers.h" #include "storage/browser/quota/quota_callbacks.h" diff --git a/chromium/storage/browser/quota/quota_task.cc b/chromium/storage/browser/quota/quota_task.cc index a0bda596a3a..55ade2b2bd1 100644 --- a/chromium/storage/browser/quota/quota_task.cc +++ b/chromium/storage/browser/quota/quota_task.cc @@ -58,9 +58,8 @@ void QuotaTask::DeleteSoon() { // QuotaTaskObserver ------------------------------------------------------- QuotaTaskObserver::~QuotaTaskObserver() { - std::for_each(running_quota_tasks_.begin(), - running_quota_tasks_.end(), - std::mem_fun(&QuotaTask::Abort)); + for (auto* task : running_quota_tasks_) + task->Abort(); } QuotaTaskObserver::QuotaTaskObserver() { diff --git a/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc b/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc index 0fdc49a03fb..9174377c8fa 100644 --- a/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc +++ b/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc @@ -29,12 +29,15 @@ const int64_t kMBytes = 1024 * 1024; const double kUsageRatioToStartEviction = 0.7; const int kThresholdOfErrorsToStopEviction = 5; const int kHistogramReportIntervalMinutes = 60; +const double kMustRemainAvailableRatio = 0.1; +const int64_t kDefaultMustRemainAvailableSpace = 1024 * kMBytes; +const double kDiskSpaceShortageAllowanceRatio = 0.5; } namespace storage { const int QuotaTemporaryStorageEvictor:: - kMinAvailableDiskSpaceToStartEvictionNotSpecified = -1; + kMinAvailableToStartEvictionNotSpecified = -1; QuotaTemporaryStorageEvictor::EvictionRoundStatistics::EvictionRoundStatistics() : in_round(false), @@ -49,8 +52,8 @@ QuotaTemporaryStorageEvictor::EvictionRoundStatistics::EvictionRoundStatistics() QuotaTemporaryStorageEvictor::QuotaTemporaryStorageEvictor( QuotaEvictionHandler* quota_eviction_handler, int64_t interval_ms) - : min_available_disk_space_to_start_eviction_( - kMinAvailableDiskSpaceToStartEvictionNotSpecified), + : min_available_to_start_eviction_( + kMinAvailableToStartEvictionNotSpecified), quota_eviction_handler_(quota_eviction_handler), interval_ms_(interval_ms), repeated_eviction_(true), @@ -159,13 +162,33 @@ void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay(int delay_ms) { void QuotaTemporaryStorageEvictor::ConsiderEviction() { OnEvictionRoundStarted(); - // Get usage and disk space, then continue. + if (min_available_to_start_eviction_ == + kMinAvailableToStartEvictionNotSpecified) { + quota_eviction_handler_->AsyncGetVolumeInfo( + base::Bind(&QuotaTemporaryStorageEvictor::OnGotVolumeInfo, + weak_factory_.GetWeakPtr())); + } else { + quota_eviction_handler_->GetUsageAndQuotaForEviction( + base::Bind(&QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction, + weak_factory_.GetWeakPtr(), + min_available_to_start_eviction_)); + } +} + +void QuotaTemporaryStorageEvictor::OnGotVolumeInfo( + bool success, uint64_t available_space, uint64_t total_size) { + // Compute how much to keep free as a function of total disk size. + int64_t must_remain_available_space = success ? + static_cast<int64_t>(total_size * kMustRemainAvailableRatio) : + kDefaultMustRemainAvailableSpace; + quota_eviction_handler_->GetUsageAndQuotaForEviction( base::Bind(&QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), must_remain_available_space)); } void QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction( + int64_t must_remain_available_space, QuotaStatusCode status, const UsageAndQuota& qau) { DCHECK(CalledOnValidThread()); @@ -180,11 +203,16 @@ void QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction( static_cast<int64_t>(0), usage - static_cast<int64_t>(qau.quota * kUsageRatioToStartEviction)); - // min_available_disk_space_to_start_eviction_ might be < 0 if no value - // is explicitly configured yet. int64_t diskspace_shortage = std::max( static_cast<int64_t>(0), - min_available_disk_space_to_start_eviction_ - qau.available_disk_space); + must_remain_available_space - qau.available_disk_space); + + // If we're using so little that freeing all of it wouldn't help, + // don't let the low space condition cause us to delete it all. + if (usage < static_cast<int64_t>(diskspace_shortage * + kDiskSpaceShortageAllowanceRatio)) { + diskspace_shortage = 0; + } if (!round_statistics_.is_initialized) { round_statistics_.usage_overage_at_round = usage_overage; diff --git a/chromium/storage/browser/quota/quota_temporary_storage_evictor.h b/chromium/storage/browser/quota/quota_temporary_storage_evictor.h index f3cdf3a3b82..8039426bca6 100644 --- a/chromium/storage/browser/quota/quota_temporary_storage_evictor.h +++ b/chromium/storage/browser/quota/quota_temporary_storage_evictor.h @@ -78,15 +78,12 @@ class STORAGE_EXPORT QuotaTemporaryStorageEvictor : public base::NonThreadSafe { void ReportPerHourHistogram(); void Start(); - int64_t min_available_disk_space_to_start_eviction() { - return min_available_disk_space_to_start_eviction_; - } void reset_min_available_disk_space_to_start_eviction() { - min_available_disk_space_to_start_eviction_ = - kMinAvailableDiskSpaceToStartEvictionNotSpecified; + min_available_to_start_eviction_ = + kMinAvailableToStartEvictionNotSpecified; } void set_min_available_disk_space_to_start_eviction(int64_t value) { - min_available_disk_space_to_start_eviction_ = value; + min_available_to_start_eviction_ = value; } private: @@ -94,7 +91,11 @@ class STORAGE_EXPORT QuotaTemporaryStorageEvictor : public base::NonThreadSafe { void StartEvictionTimerWithDelay(int delay_ms); void ConsiderEviction(); + void OnGotVolumeInfo(bool success, + uint64_t available_space, + uint64_t total_size); void OnGotUsageAndQuotaForEviction( + int64_t must_remain_available_space, QuotaStatusCode status, const UsageAndQuota& quota_and_usage); void OnGotEvictionOrigin(const GURL& origin); @@ -108,9 +109,9 @@ class STORAGE_EXPORT QuotaTemporaryStorageEvictor : public base::NonThreadSafe { repeated_eviction_ = repeated_eviction; } - static const int kMinAvailableDiskSpaceToStartEvictionNotSpecified; + static const int kMinAvailableToStartEvictionNotSpecified; - int64_t min_available_disk_space_to_start_eviction_; + int64_t min_available_to_start_eviction_; // Not owned; quota_eviction_handler owns us. QuotaEvictionHandler* quota_eviction_handler_; diff --git a/chromium/storage/browser/quota/storage_monitor.cc b/chromium/storage/browser/quota/storage_monitor.cc index 41ef41b7377..a0d351fbdd1 100644 --- a/chromium/storage/browser/quota/storage_monitor.cc +++ b/chromium/storage/browser/quota/storage_monitor.cc @@ -10,7 +10,7 @@ #include "base/stl_util.h" #include "base/trace_event/trace_event.h" -#include "net/base/net_util.h" +#include "net/base/url_util.h" #include "storage/browser/quota/quota_manager.h" #include "storage/common/quota/quota_status_code.h" diff --git a/chromium/storage/browser/quota/usage_tracker.h b/chromium/storage/browser/quota/usage_tracker.h index e62b292f26f..994fc584635 100644 --- a/chromium/storage/browser/quota/usage_tracker.h +++ b/chromium/storage/browser/quota/usage_tracker.h @@ -8,12 +8,12 @@ #include <stdint.h> #include <map> +#include <memory> #include <set> #include <string> #include "base/callback.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/threading/non_thread_safe.h" #include "storage/browser/quota/quota_callbacks.h" #include "storage/browser/quota/quota_client.h" diff --git a/chromium/storage/common/blob_storage/blob_item_bytes_request.cc b/chromium/storage/common/blob_storage/blob_item_bytes_request.cc index 2f087721e3c..a724c435c36 100644 --- a/chromium/storage/common/blob_storage/blob_item_bytes_request.cc +++ b/chromium/storage/common/blob_storage/blob_item_bytes_request.cc @@ -10,20 +10,20 @@ namespace storage { BlobItemBytesRequest BlobItemBytesRequest::CreateIPCRequest( - size_t request_number, - size_t renderer_item_index, - size_t renderer_item_offset, - size_t size) { + uint32_t request_number, + uint32_t renderer_item_index, + uint64_t renderer_item_offset, + uint64_t size) { return BlobItemBytesRequest(request_number, IPCBlobItemRequestStrategy::IPC, renderer_item_index, renderer_item_offset, size, kInvalidIndex, kInvalidSize); } BlobItemBytesRequest BlobItemBytesRequest::CreateSharedMemoryRequest( - size_t request_number, - size_t renderer_item_index, - size_t renderer_item_offset, - size_t size, - size_t handle_index, + uint32_t request_number, + uint32_t renderer_item_index, + uint64_t renderer_item_offset, + uint64_t size, + uint32_t handle_index, uint64_t handle_offset) { return BlobItemBytesRequest(request_number, IPCBlobItemRequestStrategy::SHARED_MEMORY, @@ -32,11 +32,11 @@ BlobItemBytesRequest BlobItemBytesRequest::CreateSharedMemoryRequest( } BlobItemBytesRequest BlobItemBytesRequest::CreateFileRequest( - size_t request_number, - size_t renderer_item_index, + uint32_t request_number, + uint32_t renderer_item_index, uint64_t renderer_item_offset, uint64_t size, - size_t handle_index, + uint32_t handle_index, uint64_t handle_offset) { return BlobItemBytesRequest(request_number, IPCBlobItemRequestStrategy::FILE, renderer_item_index, renderer_item_offset, size, @@ -53,12 +53,12 @@ BlobItemBytesRequest::BlobItemBytesRequest() handle_offset(kInvalidSize) {} BlobItemBytesRequest::BlobItemBytesRequest( - size_t request_number, + uint32_t request_number, IPCBlobItemRequestStrategy transport_strategy, - size_t renderer_item_index, + uint32_t renderer_item_index, uint64_t renderer_item_offset, uint64_t size, - size_t handle_index, + uint32_t handle_index, uint64_t handle_offset) : request_number(request_number), transport_strategy(transport_strategy), diff --git a/chromium/storage/common/blob_storage/blob_item_bytes_request.h b/chromium/storage/common/blob_storage/blob_item_bytes_request.h index 11a619ce1e2..3c0e8c764f9 100644 --- a/chromium/storage/common/blob_storage/blob_item_bytes_request.h +++ b/chromium/storage/common/blob_storage/blob_item_bytes_request.h @@ -15,50 +15,51 @@ namespace storage { // This class is serialized over IPC to request bytes from a blob item. +// We are using uint32_t for the indexes struct STORAGE_COMMON_EXPORT BlobItemBytesRequest { // Not using std::numeric_limits<T>::max() because of non-C++11 builds. - static const size_t kInvalidIndex = SIZE_MAX; + static const uint32_t kInvalidIndex = UINT32_MAX; static const uint64_t kInvalidSize = UINT64_MAX; - static BlobItemBytesRequest CreateIPCRequest(size_t request_number, - size_t renderer_item_index, - size_t renderer_item_offset, - size_t size); + static BlobItemBytesRequest CreateIPCRequest(uint32_t request_number, + uint32_t renderer_item_index, + uint64_t renderer_item_offset, + uint64_t size); static BlobItemBytesRequest CreateSharedMemoryRequest( - size_t request_number, - size_t renderer_item_index, - size_t renderer_item_offset, - size_t size, - size_t handle_index, + uint32_t request_number, + uint32_t renderer_item_index, + uint64_t renderer_item_offset, + uint64_t size, + uint32_t handle_index, uint64_t handle_offset); - static BlobItemBytesRequest CreateFileRequest(size_t request_number, - size_t renderer_item_index, + static BlobItemBytesRequest CreateFileRequest(uint32_t request_number, + uint32_t renderer_item_index, uint64_t renderer_item_offset, uint64_t size, - size_t handle_index, + uint32_t handle_index, uint64_t handle_offset); BlobItemBytesRequest(); - BlobItemBytesRequest(size_t request_number, + BlobItemBytesRequest(uint32_t request_number, IPCBlobItemRequestStrategy transport_strategy, - size_t renderer_item_index, + uint32_t renderer_item_index, uint64_t renderer_item_offset, uint64_t size, - size_t handle_index, + uint32_t handle_index, uint64_t handle_offset); ~BlobItemBytesRequest(); // The request number uniquely identifies the memory request. We can't use // the renderer item index or browser item index as there can be multiple // requests for both (as segmentation boundaries can exist in both). - size_t request_number; + uint32_t request_number; IPCBlobItemRequestStrategy transport_strategy; - size_t renderer_item_index; + uint32_t renderer_item_index; uint64_t renderer_item_offset; uint64_t size; - size_t handle_index; + uint32_t handle_index; uint64_t handle_offset; }; diff --git a/chromium/storage/common/blob_storage/blob_item_bytes_response.cc b/chromium/storage/common/blob_storage/blob_item_bytes_response.cc index 40c0781954a..493804ff934 100644 --- a/chromium/storage/common/blob_storage/blob_item_bytes_response.cc +++ b/chromium/storage/common/blob_storage/blob_item_bytes_response.cc @@ -16,9 +16,12 @@ namespace storage { BlobItemBytesResponse::BlobItemBytesResponse() : request_number(kInvalidIndex) {} -BlobItemBytesResponse::BlobItemBytesResponse(size_t request_number) +BlobItemBytesResponse::BlobItemBytesResponse(uint32_t request_number) : request_number(request_number) {} +BlobItemBytesResponse::BlobItemBytesResponse( + const BlobItemBytesResponse& other) = default; + BlobItemBytesResponse::~BlobItemBytesResponse() {} void PrintTo(const BlobItemBytesResponse& response, ::std::ostream* os) { diff --git a/chromium/storage/common/blob_storage/blob_item_bytes_response.h b/chromium/storage/common/blob_storage/blob_item_bytes_response.h index 189313ff6f9..7248ce6a33a 100644 --- a/chromium/storage/common/blob_storage/blob_item_bytes_response.h +++ b/chromium/storage/common/blob_storage/blob_item_bytes_response.h @@ -11,27 +11,30 @@ #include <ostream> #include <vector> +#include "base/time/time.h" #include "storage/common/storage_common_export.h" namespace storage { // This class is serialized over IPC to send blob item data, or to signal that -// the memory has been populated. +// the memory has been populated in shared memory or a file. struct STORAGE_COMMON_EXPORT BlobItemBytesResponse { // not using std::numeric_limits<T>::max() because of non-C++11 builds. - static const size_t kInvalidIndex = SIZE_MAX; + static const uint32_t kInvalidIndex = UINT32_MAX; BlobItemBytesResponse(); - explicit BlobItemBytesResponse(size_t request_number); + explicit BlobItemBytesResponse(uint32_t request_number); + BlobItemBytesResponse(const BlobItemBytesResponse& other); ~BlobItemBytesResponse(); - char* allocate_mutable_data(size_t size) { + char* allocate_mutable_data(uint32_t size) { inline_data.resize(size); return &inline_data[0]; } - size_t request_number; + uint32_t request_number; std::vector<char> inline_data; + base::Time time_file_modified; }; STORAGE_COMMON_EXPORT void PrintTo(const BlobItemBytesResponse& response, diff --git a/chromium/storage/common/blob_storage/blob_storage_constants.h b/chromium/storage/common/blob_storage/blob_storage_constants.h index e77c8683527..0fc10c583ce 100644 --- a/chromium/storage/common/blob_storage/blob_storage_constants.h +++ b/chromium/storage/common/blob_storage/blob_storage_constants.h @@ -28,11 +28,25 @@ enum class IPCBlobItemRequestStrategy { LAST = FILE }; +// These items cannot be reordered or renumbered because they're recorded to +// UMA. New items must be added immediately before LAST, and LAST must be set to +// the the last item. enum class IPCBlobCreationCancelCode { UNKNOWN = 0, - OUT_OF_MEMORY, - FILE_WRITE_FAILED, - LAST = FILE_WRITE_FAILED + OUT_OF_MEMORY = 1, + // We couldn't create or write to a file. File system error, like a full disk. + FILE_WRITE_FAILED = 2, + // The renderer was destroyed while data was in transit. + SOURCE_DIED_IN_TRANSIT = 3, + // The renderer destructed the blob before it was done transferring, and there + // were no outstanding references (no one is waiting to read) to keep the + // blob alive. + BLOB_DEREFERENCED_WHILE_BUILDING = 4, + // A blob that we referenced during construction is broken, or a browser-side + // builder tries to build a blob with a blob reference that isn't finished + // constructing. + REFERENCED_BLOB_BROKEN = 5, + LAST = REFERENCED_BLOB_BROKEN }; } // namespace storage diff --git a/chromium/storage/common/data_element.cc b/chromium/storage/common/data_element.cc index 821badb9630..ea11f4309d6 100644 --- a/chromium/storage/common/data_element.cc +++ b/chromium/storage/common/data_element.cc @@ -19,6 +19,8 @@ DataElement::DataElement() offset_(0), length_(std::numeric_limits<uint64_t>::max()) {} +DataElement::DataElement(const DataElement& other) = default; + DataElement::~DataElement() {} void DataElement::SetToFilePathRange( diff --git a/chromium/storage/common/data_element.h b/chromium/storage/common/data_element.h index 2f28c401f3e..08fea6e6767 100644 --- a/chromium/storage/common/data_element.h +++ b/chromium/storage/common/data_element.h @@ -38,6 +38,7 @@ class STORAGE_COMMON_EXPORT DataElement { }; DataElement(); + DataElement(const DataElement& other); ~DataElement(); Type type() const { return type_; } diff --git a/chromium/storage/common/database/database_identifier.cc b/chromium/storage/common/database/database_identifier.cc index 2c1aa552270..e34f2285fcf 100644 --- a/chromium/storage/common/database/database_identifier.cc +++ b/chromium/storage/common/database/database_identifier.cc @@ -13,6 +13,38 @@ namespace storage { +namespace { + + +// If the passed string is of the form "[1::2:3]", returns "[1__2_3]". +std::string EscapeIPv6Hostname(const std::string& hostname) { + // Shortest IPv6 hostname would be "[::1]". + if (hostname.length() < 5 || hostname.front() != '[' || + hostname.back() != ']') + return hostname; + + // Should be canonicalized before it gets this far. + // i.e. "[::ffff:8190:3426]" not "[::FFFF:129.144.52.38]" + DCHECK(base::ContainsOnlyChars(hostname, "[]:0123456789abcdef")); + + std::string copy = hostname; + base::ReplaceChars(hostname, ":", "_", ©); + return copy; +} + +// If the passed string is of the form "[1__2_3]", returns "[1::2:3]". +std::string UnescapeIPv6Hostname(const std::string& hostname) { + if (hostname.length() < 5 || hostname.front() != '[' || + hostname.back() != ']') + return hostname; + + std::string copy = hostname; + base::ReplaceChars(hostname, "_", ":", ©); + return copy; +} + +} // namespace + // static std::string GetIdentifierFromOrigin(const GURL& origin) { return DatabaseIdentifier::CreateFromOrigin(origin).ToString(); @@ -23,6 +55,11 @@ GURL GetOriginFromIdentifier(const std::string& identifier) { return DatabaseIdentifier::Parse(identifier).ToOrigin(); } +// static +bool IsValidOriginIdentifier(const std::string& identifier) { + return GetOriginFromIdentifier(identifier).is_valid(); +} + static bool SchemeIsUnique(const std::string& scheme) { return scheme == "about" || scheme == "data" || scheme == "javascript"; } @@ -93,8 +130,10 @@ DatabaseIdentifier DatabaseIdentifier::Parse(const std::string& identifier) { if (!base::StringToInt(port_str, &port) || port < 0 || port >= 1 << 16) return DatabaseIdentifier(); - std::string hostname(identifier.data() + first_underscore + 1, - last_underscore - first_underscore - 1); + std::string hostname = + UnescapeIPv6Hostname(std::string(identifier.data() + first_underscore + 1, + last_underscore - first_underscore - 1)); + GURL url(scheme + "://" + hostname + "/"); if (!url.IsStandard()) @@ -132,7 +171,8 @@ std::string DatabaseIdentifier::ToString() const { return "file__0"; if (is_unique_) return "__0"; - return scheme_ + "_" + hostname_ + "_" + base::IntToString(port_); + return scheme_ + "_" + EscapeIPv6Hostname(hostname_) + "_" + + base::IntToString(port_); } GURL DatabaseIdentifier::ToOrigin() const { diff --git a/chromium/storage/common/database/database_identifier.h b/chromium/storage/common/database/database_identifier.h index a37e2ad76d0..b17f4eff232 100644 --- a/chromium/storage/common/database/database_identifier.h +++ b/chromium/storage/common/database/database_identifier.h @@ -17,6 +17,8 @@ STORAGE_COMMON_EXPORT std::string GetIdentifierFromOrigin( const GURL& origin); STORAGE_COMMON_EXPORT GURL GetOriginFromIdentifier( const std::string& identifier); +STORAGE_COMMON_EXPORT bool IsValidOriginIdentifier( + const std::string& identifier); class STORAGE_COMMON_EXPORT DatabaseIdentifier { public: diff --git a/chromium/storage/common/fileapi/file_system_types.h b/chromium/storage/common/fileapi/file_system_types.h index 645b759170d..3f4f942cd9e 100644 --- a/chromium/storage/common/fileapi/file_system_types.h +++ b/chromium/storage/common/fileapi/file_system_types.h @@ -81,9 +81,6 @@ enum FileSystemType { // Indicates a synthetic iTunes filesystem. kFileSystemTypeItunes, - // Indicates a synthetic iPhoto filesystem. - kFileSystemTypeIphoto, - // Indicates a Drive filesystem which provides access to Google Drive. kFileSystemTypeDrive, diff --git a/chromium/storage/common/fileapi/file_system_util.cc b/chromium/storage/common/fileapi/file_system_util.cc index 4ce1657f112..3bb9b14f4f4 100644 --- a/chromium/storage/common/fileapi/file_system_util.cc +++ b/chromium/storage/common/fileapi/file_system_util.cc @@ -184,7 +184,8 @@ bool ParseFileSystemSchemeURL(const GURL& url, return false; std::string path = net::UnescapeURLComponent(url.path(), - net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS | + net::UnescapeRule::SPACES | net::UnescapeRule::PATH_SEPARATORS | + net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS | net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS); // Ensure the path is relative. @@ -303,8 +304,6 @@ std::string GetFileSystemTypeString(FileSystemType type) { return "Picasa"; case kFileSystemTypeItunes: return "Itunes"; - case kFileSystemTypeIphoto: - return "Iphoto"; case kFileSystemTypeDrive: return "Drive"; case kFileSystemTypeSyncable: diff --git a/chromium/storage/storage_browser.gyp b/chromium/storage/storage_browser.gyp index 87a11861699..f088ac1c7ee 100644 --- a/chromium/storage/storage_browser.gyp +++ b/chromium/storage/storage_browser.gyp @@ -27,8 +27,8 @@ 'sources': [ 'browser/blob/blob_async_builder_host.cc', 'browser/blob/blob_async_builder_host.h', - 'browser/blob/blob_async_transport_strategy.cc', - 'browser/blob/blob_async_transport_strategy.h', + 'browser/blob/blob_async_transport_request_builder.cc', + 'browser/blob/blob_async_transport_request_builder.h', 'browser/blob/blob_data_builder.cc', 'browser/blob/blob_data_builder.h', 'browser/blob/blob_data_handle.cc', |