blob: b701c033bc0e9404c9f3af7e428922afb150170a [file] [log] [blame]
[email protected]c7199a6e2013-06-04 12:56:011// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]22339b12010-08-27 18:29:242// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]c7199a6e2013-06-04 12:56:015#include "content/child/webblobregistry_impl.h"
[email protected]22339b12010-08-27 18:29:246
[email protected]728c2ee2013-06-25 04:01:077#include "base/files/file_path.h"
[email protected]84388892013-09-07 04:20:188#include "base/guid.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/ref_counted.h"
[email protected]9cc992b2013-07-17 06:30:3610#include "base/memory/shared_memory.h"
[email protected]e55f5642013-07-18 00:22:5411#include "base/message_loop/message_loop.h"
[email protected]10208ea2013-06-06 20:08:0312#include "content/child/child_thread.h"
13#include "content/child/thread_safe_sender.h"
[email protected]16dd6e22012-03-01 19:08:2014#include "content/common/fileapi/webblob_messages.h"
[email protected]5c30b5e02013-05-30 03:46:0815#include "third_party/WebKit/public/platform/WebBlobData.h"
16#include "third_party/WebKit/public/platform/WebString.h"
[email protected]61a741e2013-06-17 09:12:1217#include "third_party/WebKit/public/platform/WebThreadSafeData.h"
[email protected]5c30b5e02013-05-30 03:46:0818#include "third_party/WebKit/public/platform/WebURL.h"
[email protected]b76b556d2013-05-29 03:09:4319#include "webkit/common/blob/blob_data.h"
[email protected]22339b12010-08-27 18:29:2420
21using WebKit::WebBlobData;
[email protected]22339b12010-08-27 18:29:2422using WebKit::WebString;
[email protected]61a741e2013-06-17 09:12:1223using WebKit::WebThreadSafeData;
[email protected]22339b12010-08-27 18:29:2424using WebKit::WebURL;
25
[email protected]eb398192012-10-22 20:16:1926namespace content {
27
[email protected]90b37772013-08-06 07:45:2328namespace {
29
30const size_t kLargeThresholdBytes = 250 * 1024;
31const size_t kMaxSharedMemoryBytes = 10 * 1024 * 1024;
32
33} // namespace
34
[email protected]b180a0bb2013-03-06 00:36:1035WebBlobRegistryImpl::WebBlobRegistryImpl(ThreadSafeSender* sender)
36 : sender_(sender) {
[email protected]22339b12010-08-27 18:29:2437}
38
39WebBlobRegistryImpl::~WebBlobRegistryImpl() {
40}
41
[email protected]84388892013-09-07 04:20:1842void WebBlobRegistryImpl::registerBlobData(
43 const WebKit::WebString& uuid, const WebKit::WebBlobData& data) {
44 const std::string uuid_str(uuid.utf8());
45
46 sender_->Send(new BlobHostMsg_StartBuilding(uuid_str));
47 size_t i = 0;
48 WebBlobData::Item data_item;
49 while (data.itemAt(i++, data_item)) {
50 switch (data_item.type) {
51 case WebBlobData::Item::TypeData: {
52 // WebBlobData does not allow partial data items.
53 DCHECK(!data_item.offset && data_item.length == -1);
54 SendDataForBlob(uuid_str, data_item.data);
55 break;
56 }
57 case WebBlobData::Item::TypeFile:
58 if (data_item.length) {
59 webkit_blob::BlobData::Item item;
60 item.SetToFilePathRange(
61 base::FilePath::FromUTF16Unsafe(data_item.filePath),
62 static_cast<uint64>(data_item.offset),
63 static_cast<uint64>(data_item.length),
64 base::Time::FromDoubleT(data_item.expectedModificationTime));
65 sender_->Send(
66 new BlobHostMsg_AppendBlobDataItem(uuid_str, item));
67 }
68 break;
69 case WebBlobData::Item::TypeBlob:
70 if (data_item.length) {
71 webkit_blob::BlobData::Item item;
72 item.SetToBlobUrlRange(
73 data_item.blobURL,
74 static_cast<uint64>(data_item.offset),
75 static_cast<uint64>(data_item.length));
76 sender_->Send(
77 new BlobHostMsg_AppendBlobDataItem(uuid_str, item));
78 }
79 break;
80 case WebBlobData::Item::TypeURL:
81 if (data_item.length) {
82 // We only support filesystem URL as of now.
83 DCHECK(GURL(data_item.url).SchemeIsFileSystem());
84 webkit_blob::BlobData::Item item;
85 item.SetToFileSystemUrlRange(
86 data_item.url,
87 static_cast<uint64>(data_item.offset),
88 static_cast<uint64>(data_item.length),
89 base::Time::FromDoubleT(data_item.expectedModificationTime));
90 sender_->Send(
91 new BlobHostMsg_AppendBlobDataItem(uuid_str, item));
92 }
93 break;
94 default:
95 NOTREACHED();
96 }
97 }
98 sender_->Send(new BlobHostMsg_FinishBuilding(
99 uuid_str, data.contentType().utf8().data()));
100}
101
102void WebBlobRegistryImpl::addBlobDataRef(const WebString& uuid) {
103 sender_->Send(new BlobHostMsg_IncrementRefCount(uuid.utf8()));
104}
105
106void WebBlobRegistryImpl::removeBlobDataRef(const WebString& uuid) {
107 sender_->Send(new BlobHostMsg_DecrementRefCount(uuid.utf8()));
108}
109
110void WebBlobRegistryImpl::registerPublicBlobURL(
111 const WebURL& url, const WebString& uuid) {
112 sender_->Send(new BlobHostMsg_RegisterPublicURL(url, uuid.utf8()));
113}
114
115void WebBlobRegistryImpl::revokePublicBlobURL(const WebURL& url) {
116 sender_->Send(new BlobHostMsg_RevokePublicURL(url));
117}
118
119void WebBlobRegistryImpl::SendDataForBlob(const std::string& uuid_str,
[email protected]90b37772013-08-06 07:45:23120 const WebThreadSafeData& data) {
[email protected]61a741e2013-06-17 09:12:12121
122 if (data.size() == 0)
123 return;
124 if (data.size() < kLargeThresholdBytes) {
[email protected]90b37772013-08-06 07:45:23125 webkit_blob::BlobData::Item item;
126 item.SetToBytes(data.data(), data.size());
[email protected]84388892013-09-07 04:20:18127 sender_->Send(new BlobHostMsg_AppendBlobDataItem(uuid_str, item));
[email protected]61a741e2013-06-17 09:12:12128 } else {
129 // We handle larger amounts of data via SharedMemory instead of
130 // writing it directly to the IPC channel.
[email protected]61a741e2013-06-17 09:12:12131 size_t shared_memory_size = std::min(
[email protected]90b37772013-08-06 07:45:23132 data.size(), kMaxSharedMemoryBytes);
[email protected]61a741e2013-06-17 09:12:12133 scoped_ptr<base::SharedMemory> shared_memory(
134 ChildThread::AllocateSharedMemory(shared_memory_size,
135 sender_.get()));
136 CHECK(shared_memory.get());
[email protected]90b37772013-08-06 07:45:23137
138 size_t data_size = data.size();
139 const char* data_ptr = data.data();
[email protected]61a741e2013-06-17 09:12:12140 while (data_size) {
141 size_t chunk_size = std::min(data_size, shared_memory_size);
142 memcpy(shared_memory->memory(), data_ptr, chunk_size);
143 sender_->Send(new BlobHostMsg_SyncAppendSharedMemory(
[email protected]84388892013-09-07 04:20:18144 uuid_str, shared_memory->handle(), chunk_size));
[email protected]61a741e2013-06-17 09:12:12145 data_size -= chunk_size;
146 data_ptr += chunk_size;
147 }
148 }
149}
150
[email protected]84388892013-09-07 04:20:18151// DEPRECATED, almost. Until blink is updated, we implement these older methods
152// in terms of our newer blob storage system. We create a uuid for each 'data'
153// we see and construct a mapping from the private blob urls we're given to
154// that uuid. The mapping is maintained in the browser process.
155//
156// Chromium is setup to speak in terms of old-style private blob urls or
157// new-style uuid identifiers. Once blink has been migrated support for
158// the old-style will be deleted. Search for the term deprecated.
159
[email protected]22339b12010-08-27 18:29:24160void WebBlobRegistryImpl::registerBlobURL(
161 const WebURL& url, WebBlobData& data) {
[email protected]84388892013-09-07 04:20:18162 std::string uuid = base::GenerateGUID();
163 registerBlobData(WebKit::WebString::fromUTF8(uuid), data);
164 sender_->Send(new BlobHostMsg_DeprecatedRegisterBlobURL(url, uuid));
165 sender_->Send(new BlobHostMsg_DecrementRefCount(uuid));
[email protected]22339b12010-08-27 18:29:24166}
167
168void WebBlobRegistryImpl::registerBlobURL(
169 const WebURL& url, const WebURL& src_url) {
[email protected]84388892013-09-07 04:20:18170 sender_->Send(new BlobHostMsg_DeprecatedCloneBlobURL(url, src_url));
[email protected]22339b12010-08-27 18:29:24171}
172
173void WebBlobRegistryImpl::unregisterBlobURL(const WebURL& url) {
[email protected]84388892013-09-07 04:20:18174 sender_->Send(new BlobHostMsg_DeprecatedRevokeBlobURL(url));
[email protected]90b37772013-08-06 07:45:23175}
176
[email protected]84388892013-09-07 04:20:18177
178// ------ streams stuff -----
179
[email protected]90b37772013-08-06 07:45:23180void WebBlobRegistryImpl::registerStreamURL(
181 const WebURL& url, const WebString& content_type) {
182 DCHECK(ChildThread::current());
183 sender_->Send(new StreamHostMsg_StartBuilding(url, content_type.utf8()));
184}
185
186void WebBlobRegistryImpl::registerStreamURL(
187 const WebURL& url, const WebURL& src_url) {
188 DCHECK(ChildThread::current());
189 sender_->Send(new StreamHostMsg_Clone(url, src_url));
190}
191
192void WebBlobRegistryImpl::addDataToStream(const WebURL& url,
193 WebThreadSafeData& data) {
194 DCHECK(ChildThread::current());
195 if (data.size() == 0)
196 return;
197 if (data.size() < kLargeThresholdBytes) {
198 webkit_blob::BlobData::Item item;
199 item.SetToBytes(data.data(), data.size());
200 sender_->Send(new StreamHostMsg_AppendBlobDataItem(url, item));
201 } else {
202 // We handle larger amounts of data via SharedMemory instead of
203 // writing it directly to the IPC channel.
204 size_t shared_memory_size = std::min(
205 data.size(), kMaxSharedMemoryBytes);
206 scoped_ptr<base::SharedMemory> shared_memory(
207 ChildThread::AllocateSharedMemory(shared_memory_size,
208 sender_.get()));
209 CHECK(shared_memory.get());
210
211 size_t data_size = data.size();
212 const char* data_ptr = data.data();
213 while (data_size) {
214 size_t chunk_size = std::min(data_size, shared_memory_size);
215 memcpy(shared_memory->memory(), data_ptr, chunk_size);
216 sender_->Send(new StreamHostMsg_SyncAppendSharedMemory(
217 url, shared_memory->handle(), chunk_size));
218 data_size -= chunk_size;
219 data_ptr += chunk_size;
220 }
221 }
222}
223
224void WebBlobRegistryImpl::finalizeStream(const WebURL& url) {
225 DCHECK(ChildThread::current());
226 sender_->Send(new StreamHostMsg_FinishBuilding(url));
227}
228
[email protected]7bd8ed12013-08-28 13:36:39229void WebBlobRegistryImpl::abortStream(const WebURL& url) {
230 DCHECK(ChildThread::current());
231 sender_->Send(new StreamHostMsg_AbortBuilding(url));
232}
233
[email protected]90b37772013-08-06 07:45:23234void WebBlobRegistryImpl::unregisterStreamURL(const WebURL& url) {
235 DCHECK(ChildThread::current());
236 sender_->Send(new StreamHostMsg_Remove(url));
[email protected]22339b12010-08-27 18:29:24237}
[email protected]eb398192012-10-22 20:16:19238
239} // namespace content