| Index: storage/browser/blob/blob_transport_host.h
|
| diff --git a/storage/browser/blob/blob_transport_host.h b/storage/browser/blob/blob_transport_host.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f8e952a787a408aafa1eddb4621c9d4f225b3bca
|
| --- /dev/null
|
| +++ b/storage/browser/blob/blob_transport_host.h
|
| @@ -0,0 +1,186 @@
|
| +// 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_HOST_H_
|
| +#define STORAGE_BROWSER_BLOB_BLOB_TRANSPORT_HOST_H_
|
| +
|
| +#include <stddef.h>
|
| +#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/shared_memory_handle.h"
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "storage/browser/blob/blob_data_builder.h"
|
| +#include "storage/browser/blob/blob_memory_controller.h"
|
| +#include "storage/browser/blob/blob_transport_request_builder.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"
|
| +#include "storage/common/blob_storage/blob_storage_constants.h"
|
| +#include "storage/common/data_element.h"
|
| +
|
| +namespace base {
|
| +class SharedMemory;
|
| +}
|
| +
|
| +namespace storage {
|
| +class BlobDataHandle;
|
| +class BlobStorageContext;
|
| +
|
| +// This class facilitates moving memory from the renderer to the browser.
|
| +class STORAGE_EXPORT BlobTransportHost {
|
| + public:
|
| + // One is expected to use std::move when calling this callback.
|
| + using RequestMemoryCallback =
|
| + base::Callback<void(std::vector<storage::BlobItemBytesRequest>,
|
| + std::vector<base::SharedMemoryHandle>,
|
| + std::vector<base::File>)>;
|
| +
|
| + BlobTransportHost();
|
| + ~BlobTransportHost();
|
| +
|
| + // This registers the given blob internally and adds it to the storage with a
|
| + // refcount of 1. |completion_callback| is called synchronously or
|
| + // asynchronously with:
|
| + // * INVALID_CONSTRUCTION_ARGUMENTS if we have invalid input arguments/data.
|
| + // * REFERENCED_BLOB_BROKEN if one of the referenced blobs is broken or
|
| + // doesn't exist.
|
| + // * DONE if we don't need any more data transported and we can clean up.
|
| + // Returns a blob handle that is never null.
|
| + std::unique_ptr<BlobDataHandle> StartBuildingBlob(
|
| + const std::string& uuid,
|
| + const std::string& content_type,
|
| + const std::string& content_disposition,
|
| + const std::vector<DataElement>& elements,
|
| + BlobStorageContext* context,
|
| + const RequestMemoryCallback& request_memory,
|
| + const BlobStatusCallback& completion_callback);
|
| +
|
| + // This is called when we have responses from the Renderer to our calls to
|
| + // the request_memory callback above. The callbacks given in StartBuildingBlob
|
| + // will be used to request for more memory or signal completion.
|
| + // Note: The uuid must be being built in this host (IsBeingBuilt).
|
| + void OnMemoryResponses(const std::string& uuid,
|
| + const std::vector<BlobItemBytesResponse>& responses,
|
| + BlobStorageContext* context);
|
| +
|
| + // This removes the TransportState 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. This also calls the |completion_callback|.
|
| + // 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,
|
| + BlobStatus code,
|
| + BlobStorageContext* context);
|
| +
|
| + // This clears this object of pending construction and does NOT call transport
|
| + // complete callbacks.
|
| + 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();
|
| + }
|
| +
|
| + private:
|
| + struct TransportState {
|
| + TransportState(const std::string& uuid,
|
| + const std::string& content_type,
|
| + const std::string& content_disposition,
|
| + RequestMemoryCallback request_memory_callback,
|
| + BlobStatusCallback completion_callback);
|
| + TransportState(TransportState&&);
|
| + TransportState& operator=(TransportState&&);
|
| + DISALLOW_COPY_AND_ASSIGN(TransportState);
|
| + ~TransportState();
|
| +
|
| + IPCBlobItemRequestStrategy strategy = IPCBlobItemRequestStrategy::UNKNOWN;
|
| + BlobTransportRequestBuilder request_builder;
|
| + BlobDataBuilder data_builder;
|
| + std::vector<bool> request_received;
|
| + size_t num_fulfilled_requests = 0;
|
| +
|
| + RequestMemoryCallback request_memory_callback;
|
| + BlobStatusCallback completion_callback;
|
| +
|
| + // Used by shared memory strategy.
|
| + size_t next_request = 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 = 0;
|
| + // Only relevant if num_shared_memory_requests is > 0
|
| + size_t current_shared_memory_handle_index = 0;
|
| +
|
| + // Used by file strategy.
|
| + std::vector<scoped_refptr<ShareableFileReference>> files;
|
| + };
|
| +
|
| + typedef std::unordered_map<std::string, TransportState> AsyncBlobMap;
|
| +
|
| + void StartRequests(
|
| + const std::string& uuid,
|
| + TransportState* state,
|
| + BlobStorageContext* context,
|
| + std::vector<BlobMemoryController::FileCreationInfo> file_infos);
|
| +
|
| + void OnReadyForTransport(
|
| + const std::string& uuid,
|
| + base::WeakPtr<BlobStorageContext> context,
|
| + BlobStatus status,
|
| + std::vector<BlobMemoryController::FileCreationInfo> file_infos);
|
| +
|
| + void SendIPCRequests(TransportState* state, BlobStorageContext* context);
|
| + void OnIPCResponses(const std::string& uuid,
|
| + TransportState* state,
|
| + const std::vector<BlobItemBytesResponse>& responses,
|
| + BlobStorageContext* context);
|
| +
|
| + // This is the 'main loop' of our memory requests to the renderer.
|
| + void ContinueSharedMemoryRequests(const std::string& uuid,
|
| + TransportState* state,
|
| + BlobStorageContext* context);
|
| +
|
| + void OnSharedMemoryResponses(
|
| + const std::string& uuid,
|
| + TransportState* state,
|
| + const std::vector<BlobItemBytesResponse>& responses,
|
| + BlobStorageContext* context);
|
| +
|
| + void SendFileRequests(
|
| + TransportState* state,
|
| + BlobStorageContext* context,
|
| + std::vector<BlobMemoryController::FileCreationInfo> files);
|
| +
|
| + void OnFileResponses(const std::string& uuid,
|
| + TransportState* state,
|
| + const std::vector<BlobItemBytesResponse>& responses,
|
| + BlobStorageContext* context);
|
| +
|
| + // This finishes creating the blob in the context, decrements blob references
|
| + // that we were holding during construction, and erases our state.
|
| + void CompleteTransport(TransportState* state, BlobStorageContext* context);
|
| +
|
| + AsyncBlobMap async_blob_map_;
|
| + base::WeakPtrFactory<BlobTransportHost> ptr_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BlobTransportHost);
|
| +};
|
| +
|
| +} // namespace storage
|
| +#endif // STORAGE_BROWSER_BLOB_BLOB_TRANSPORT_HOST_H_
|
|
|