Index: content/child/blob_storage/blob_transport_controller.cc |
diff --git a/content/child/blob_storage/blob_transport_controller.cc b/content/child/blob_storage/blob_transport_controller.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..51a47c59757bb66e4e6ba5237c8a8d565e4f06ad |
--- /dev/null |
+++ b/content/child/blob_storage/blob_transport_controller.cc |
@@ -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. |
+ |
+#include "content/child/blob_storage/blob_transport_controller.h" |
+ |
+#include <vector> |
+ |
+#include "base/lazy_instance.h" |
+#include "content/child/blob_storage/blob_consolidation.h" |
+#include "content/child/thread_safe_sender.h" |
+#include "ipc/ipc_sender.h" |
+#include "storage/common/blob_storage/blob_item_bytes_request.h" |
+#include "storage/common/blob_storage/blob_item_bytes_response.h" |
+ |
+namespace content { |
+ |
+using storage::IPCBlobCreationCancelCode; |
+ |
+using ConsolidatedItem = BlobConsolidation::ConsolidatedItem; |
+using ReadStatus = BlobConsolidation::ReadStatus; |
+using ResponsesStatus = BlobTransportTemporaryHolder::ResponsesStatus; |
+ |
+namespace { |
+const size_t kLargeThresholdBytes = 250 * 1024; |
+static base::LazyInstance<BlobTransportController> controller_ = |
+ LAZY_INSTANCE_INITIALIZER; |
+} |
+ |
+BlobTransportController* BlobTransportController::GetInstance() { |
+ return controller_.Pointer(); |
+} |
+ |
+BlobTransportController::~BlobTransportController() {} |
+ |
+void BlobTransportController::InitiateBlobTransfer( |
+ const std::string& uuid, |
+ const std::string& type, |
+ scoped_ptr<BlobConsolidation> consolidation, |
+ IPC::Sender* sender) { |
+ holder_.HoldBlobConsolidation(uuid, consolidation.Pass()); |
+ |
+ std::vector<storage::DataElement> descriptions; |
+ holder_.GetDescriptions(uuid, kLargeThresholdBytes, &descriptions); |
+ // TODO(dmurph): Uncomment when IPC messages are added. |
+ // sender->Send(new BlobStorageMsg_StartBuildingBlob(uuid, type, |
+ // descriptions)); |
+} |
+ |
+void BlobTransportController::OnMemoryRequest( |
+ const std::string& uuid, |
+ const std::vector<storage::BlobItemBytesRequest>& requests, |
+ std::vector<base::SharedMemoryHandle>* memory_handles, |
+ const std::vector<IPC::PlatformFileForTransit>& file_handles, |
+ IPC::Sender* sender) { |
+ std::vector<storage::BlobItemBytesResponse> responses; |
+ ResponsesStatus status = holder_.GetResponses(uuid, requests, memory_handles, |
+ file_handles, &responses); |
+ |
+ bool success = false; |
+ switch (status) { |
+ case ResponsesStatus::BLOB_NOT_FOUND: |
+ DVLOG(1) << "Unable to find blob " << uuid << "."; |
+ return; |
+ case ResponsesStatus::INVALID_ITEM_INDEX: |
+ DVLOG(1) << "Index out of bounds for blob item in blob " << uuid << "."; |
+ break; |
+ case ResponsesStatus::INVALID_DATA_RANGE: |
+ DVLOG(1) << "Data range out of bounds for blob item in blob " << uuid |
+ << "."; |
+ break; |
+ case ResponsesStatus::INVALID_ITEM: |
+ DVLOG(1) << "Requesting data from non-memory item in blob " << uuid |
+ << "."; |
+ break; |
+ case ResponsesStatus::INVALID_HANDLE_INDEX: |
+ DVLOG(1) << "Invalid handle index for transferring in blob " << uuid |
+ << "."; |
+ break; |
+ case ResponsesStatus::SHARED_MEMORY_MAP_FAILED: |
+ // This would happen if the renderer process doesn't have enough memory |
+ // to map the shared memory, which is possible if we don't have much |
+ // memory. If this scenario happens often, we could delay the response |
+ // until we have enough memory. For now we just fail. |
+ DVLOG(1) << "Unable to map shared memory to send blob " << uuid << "."; |
+ break; |
+ case ResponsesStatus::UNKNOWN: |
+ DVLOG(1) << "Unknown error while populating data for blob " << uuid |
+ << "."; |
+ break; |
+ case ResponsesStatus::SUCCESS: |
+ success = true; |
+ break; |
+ } |
+ |
+ if (success) { |
+ // TODO(dmurph): Uncomment when IPC messages are added. |
+ // sender->Send(new BlobStorageMsg_MemoryItemResponse(uuid, responses)); |
+ } else { |
+ DVLOG(1) << "Canceling blob transfer for blob " << uuid; |
+ CancelBlobTransfer(uuid, IPCBlobCreationCancelCode::UNKNOWN, sender); |
+ } |
+} |
+ |
+void BlobTransportController::OnCancel( |
+ const std::string& uuid, |
+ storage::IPCBlobCreationCancelCode code) { |
+ DVLOG(1) << "Received blob cancel for blob " << uuid << " with reason:"; |
+ switch (code) { |
+ case IPCBlobCreationCancelCode::UNKNOWN: |
+ DVLOG(1) << "Unknown."; |
+ break; |
+ case IPCBlobCreationCancelCode::OUT_OF_MEMORY: |
+ DVLOG(1) << "Out of Memory."; |
+ break; |
+ case IPCBlobCreationCancelCode::FILE_WRITE_FAILED: |
+ DVLOG(1) << "File Write Failed (Invalid cancel reason!)."; |
+ break; |
+ } |
+ holder_.ReleaseBlob(uuid); |
+} |
+ |
+void BlobTransportController::OnDone(const std::string& uuid) { |
+ holder_.ReleaseBlob(uuid); |
+} |
+ |
+BlobTransportController::BlobTransportController() {} |
+ |
+void BlobTransportController::CancelBlobTransfer( |
+ const std::string& uuid, |
+ storage::IPCBlobCreationCancelCode code, |
+ IPC::Sender* sender) { |
+ // TODO(dmurph): Uncomment when IPC messages are added. |
+ // sender->Send(new BlobStorageMsg_CancelBuildingBlob(uuid, code)); |
+ holder_.ReleaseBlob(uuid); |
+} |
+ |
+} // namespace content |