Chromium Code Reviews

Side by Side Diff: webkit/glue/media/buffered_data_source.cc

Issue 3863002: Refactoring BufferedDataSource to work with WebURLLoader instead of a MediaResourceLoaderBridge. (Closed) Base URL: http://git.chromium.org/git/chromium.git
Patch Set: Removed unnecessary WebURLLoaders in the two unittests because windows compilation complains. Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/callback.h" 5 #include "base/callback.h"
6 #include "base/compiler_specific.h" 6 #include "base/compiler_specific.h"
7 #include "base/format_macros.h"
7 #include "base/message_loop.h" 8 #include "base/message_loop.h"
8 #include "base/process_util.h" 9 #include "base/process_util.h"
9 #include "base/stl_util-inl.h" 10 #include "base/stl_util-inl.h"
11 #include "base/string_number_conversions.h"
10 #include "base/string_util.h" 12 #include "base/string_util.h"
11 #include "media/base/filter_host.h" 13 #include "media/base/filter_host.h"
12 #include "media/base/media_format.h" 14 #include "media/base/media_format.h"
13 #include "net/base/load_flags.h" 15 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
15 #include "net/http/http_response_headers.h" 17 #include "third_party/WebKit/WebKit/chromium/public/WebKit.h"
18 #include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h"
19 #include "third_party/WebKit/WebKit/chromium/public/WebString.h"
20 #include "third_party/WebKit/WebKit/chromium/public/WebURLError.h"
16 #include "webkit/glue/media/buffered_data_source.h" 21 #include "webkit/glue/media/buffered_data_source.h"
17 #include "webkit/glue/webkit_glue.h" 22 #include "webkit/glue/webkit_glue.h"
18 #include "webkit/glue/webmediaplayer_impl.h" 23 #include "webkit/glue/webmediaplayer_impl.h"
19 24
25 using WebKit::WebFrame;
26 using WebKit::WebString;
27 using WebKit::WebURLError;
28 using WebKit::WebURLLoader;
29 using WebKit::WebURLRequest;
30 using WebKit::WebURLResponse;
31
20 namespace { 32 namespace {
21 33
22 const char kHttpScheme[] = "http"; 34 const char kHttpScheme[] = "http";
23 const char kHttpsScheme[] = "https"; 35 const char kHttpsScheme[] = "https";
24 const char kDataScheme[] = "data"; 36 const char kDataScheme[] = "data";
25 const int64 kPositionNotSpecified = -1; 37 const int64 kPositionNotSpecified = -1;
26 const int kHttpOK = 200; 38 const int kHttpOK = 200;
27 const int kHttpPartialContent = 206; 39 const int kHttpPartialContent = 206;
28 40
29 // Define the number of bytes in a megabyte. 41 // Define the number of bytes in a megabyte.
(...skipping 33 matching lines...)
63 return url.SchemeIs(kHttpScheme) || url.SchemeIs(kHttpsScheme); 75 return url.SchemeIs(kHttpScheme) || url.SchemeIs(kHttpsScheme);
64 } 76 }
65 77
66 bool IsDataProtocol(const GURL& url) { 78 bool IsDataProtocol(const GURL& url) {
67 return url.SchemeIs(kDataScheme); 79 return url.SchemeIs(kDataScheme);
68 } 80 }
69 81
70 } // namespace 82 } // namespace
71 83
72 namespace webkit_glue { 84 namespace webkit_glue {
85
73 ///////////////////////////////////////////////////////////////////////////// 86 /////////////////////////////////////////////////////////////////////////////
74 // BufferedResourceLoader 87 // BufferedResourceLoader
75 BufferedResourceLoader::BufferedResourceLoader( 88 BufferedResourceLoader::BufferedResourceLoader(
76 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory,
77 const GURL& url, 89 const GURL& url,
78 int64 first_byte_position, 90 int64 first_byte_position,
79 int64 last_byte_position) 91 int64 last_byte_position)
80 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), 92 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)),
81 deferred_(false), 93 deferred_(false),
82 defer_allowed_(true), 94 defer_allowed_(true),
83 completed_(false), 95 completed_(false),
84 range_requested_(false), 96 range_requested_(false),
85 partial_response_(false), 97 partial_response_(false),
86 bridge_factory_(bridge_factory),
87 url_(url), 98 url_(url),
88 first_byte_position_(first_byte_position), 99 first_byte_position_(first_byte_position),
89 last_byte_position_(last_byte_position), 100 last_byte_position_(last_byte_position),
90 start_callback_(NULL), 101 start_callback_(NULL),
91 bridge_(NULL),
92 offset_(0), 102 offset_(0),
93 content_length_(kPositionNotSpecified), 103 content_length_(kPositionNotSpecified),
94 instance_size_(kPositionNotSpecified), 104 instance_size_(kPositionNotSpecified),
95 read_callback_(NULL), 105 read_callback_(NULL),
96 read_position_(0), 106 read_position_(0),
97 read_size_(0), 107 read_size_(0),
98 read_buffer_(NULL), 108 read_buffer_(NULL),
99 first_offset_(0), 109 first_offset_(0),
100 last_offset_(0) { 110 last_offset_(0),
111 keep_test_loader(false) {
101 } 112 }
102 113
103 BufferedResourceLoader::~BufferedResourceLoader() { 114 BufferedResourceLoader::~BufferedResourceLoader() {
115 if (!completed_ && url_loader_.get())
116 url_loader_->cancel();
104 } 117 }
105 118
106 void BufferedResourceLoader::Start(net::CompletionCallback* start_callback, 119 void BufferedResourceLoader::Start(net::CompletionCallback* start_callback,
107 NetworkEventCallback* event_callback) { 120 NetworkEventCallback* event_callback,
121 WebFrame* frame) {
108 // Make sure we have not started. 122 // Make sure we have not started.
109 DCHECK(!bridge_.get());
110 DCHECK(!start_callback_.get()); 123 DCHECK(!start_callback_.get());
111 DCHECK(!event_callback_.get()); 124 DCHECK(!event_callback_.get());
112 DCHECK(start_callback); 125 DCHECK(start_callback);
113 DCHECK(event_callback); 126 DCHECK(event_callback);
114 127
128 // TODO(annacc): Maybe throw up an error here if frame is null?
129 if (frame == NULL)
130 return;
131
115 start_callback_.reset(start_callback); 132 start_callback_.reset(start_callback);
116 event_callback_.reset(event_callback); 133 event_callback_.reset(event_callback);
117 134
118 if (first_byte_position_ != kPositionNotSpecified) { 135 if (first_byte_position_ != kPositionNotSpecified) {
119 range_requested_ = true; 136 range_requested_ = true;
120 // TODO(hclam): server may not support range request so |offset_| may not 137 // TODO(hclam): server may not support range request so |offset_| may not
121 // equal to |first_byte_position_|. 138 // equal to |first_byte_position_|.
122 offset_ = first_byte_position_; 139 offset_ = first_byte_position_;
123 } 140 }
124 141
125 // Creates the bridge on render thread since we can only access
126 // ResourceDispatcher on this thread.
127 bridge_.reset(
128 bridge_factory_->CreateBridge(
129 url_,
130 net::LOAD_NORMAL,
131 first_byte_position_,
132 last_byte_position_));
133
134 // Increment the reference count right before we start the request. This 142 // Increment the reference count right before we start the request. This
135 // reference will be release when this request has ended. 143 // reference will be release when this request has ended.
136 AddRef(); 144 AddRef();
137 145
138 // And start the resource loading. 146 // Prepare the request.
139 bridge_->Start(this); 147 WebURLRequest request(url_);
148 request.setHTTPHeaderField(WebString::fromUTF8("Range"),
149 WebString::fromUTF8(GenerateHeaders(
150 first_byte_position_,
151 last_byte_position_)));
152 frame->setReferrerForRequest(request, WebKit::WebURL());
153 frame->dispatchWillSendRequest(request);
154
155 // This flag is for unittests as we don't want to reset |url_loader|
156 if (!keep_test_loader)
157 url_loader_.reset(WebKit::webKitClient()->createURLLoader());
158
159 // Start the resource loading.
160 url_loader_->loadAsynchronously(request, this);
140 } 161 }
141 162
142 void BufferedResourceLoader::Stop() { 163 void BufferedResourceLoader::Stop() {
143 // Reset callbacks. 164 // Reset callbacks.
144 start_callback_.reset(); 165 start_callback_.reset();
145 event_callback_.reset(); 166 event_callback_.reset();
146 read_callback_.reset(); 167 read_callback_.reset();
147 168
148 // Use the internal buffer to signal that we have been stopped. 169 // Use the internal buffer to signal that we have been stopped.
149 // TODO(hclam): Not so pretty to do this. 170 // TODO(hclam): Not so pretty to do this.
150 if (!buffer_.get()) 171 if (!buffer_.get())
151 return; 172 return;
152 173
153 // Destroy internal buffer. 174 // Destroy internal buffer.
154 buffer_.reset(); 175 buffer_.reset();
155 176
156 if (bridge_.get()) { 177 if (url_loader_.get()) {
157 // Cancel the request. This method call will cancel the request
158 // asynchronously. We may still get data or messages until we receive
159 // a response completed message.
160 if (deferred_) 178 if (deferred_)
161 bridge_->SetDefersLoading(false); 179 url_loader_->setDefersLoading(false);
162 deferred_ = false; 180 deferred_ = false;
163 bridge_->Cancel(); 181
182 if (!completed_) {
183 url_loader_->cancel();
184 completed_ = true;
185 }
164 } 186 }
165 } 187 }
166 188
167 void BufferedResourceLoader::Read(int64 position, 189 void BufferedResourceLoader::Read(int64 position,
168 int read_size, 190 int read_size,
169 uint8* buffer, 191 uint8* buffer,
170 net::CompletionCallback* read_callback) { 192 net::CompletionCallback* read_callback) {
171 DCHECK(!read_callback_.get()); 193 DCHECK(!read_callback_.get());
172 DCHECK(buffer_.get()); 194 DCHECK(buffer_.get());
173 DCHECK(read_callback); 195 DCHECK(read_callback);
(...skipping 50 matching lines...)
224 if (buffer_.get()) 246 if (buffer_.get())
225 return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1; 247 return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1;
226 return kPositionNotSpecified; 248 return kPositionNotSpecified;
227 } 249 }
228 250
229 void BufferedResourceLoader::SetAllowDefer(bool is_allowed) { 251 void BufferedResourceLoader::SetAllowDefer(bool is_allowed) {
230 defer_allowed_ = is_allowed; 252 defer_allowed_ = is_allowed;
231 DisableDeferIfNeeded(); 253 DisableDeferIfNeeded();
232 } 254 }
233 255
256 void BufferedResourceLoader::SetURLLoaderForTest(WebURLLoader* mock_loader) {
257 url_loader_.reset(mock_loader);
258 keep_test_loader = true;
259 }
260
234 ///////////////////////////////////////////////////////////////////////////// 261 /////////////////////////////////////////////////////////////////////////////
235 // BufferedResourceLoader, 262 // BufferedResourceLoader,
236 // webkit_glue::ResourceLoaderBridge::Peer implementations 263 // WebKit::WebURLLoaderClient implementations.
Alpha Left Google 2010/11/19 22:53:42 move this back to the previous line.
237 bool BufferedResourceLoader::OnReceivedRedirect(
238 const GURL& new_url,
239 const webkit_glue::ResourceResponseInfo& info,
240 bool* has_new_first_party_for_cookies,
241 GURL* new_first_party_for_cookies) {
242 DCHECK(bridge_.get());
243 264
244 // Save the new URL. 265 void BufferedResourceLoader::willSendRequest(
245 url_ = new_url; 266 WebURLLoader* loader,
246 // TODO(wtc): should we return a new first party for cookies URL? 267 WebURLRequest& newRequest,
247 *has_new_first_party_for_cookies = false; 268 const WebURLResponse& redirectResponse) {
248 269
249 // The load may have been stopped and |start_callback| is destroyed. 270 // The load may have been stopped and |start_callback| is destroyed.
250 // In this case we shouldn't do anything. 271 // In this case we shouldn't do anything.
251 if (!start_callback_.get()) 272 if (!start_callback_.get()) {
252 return true; 273 // Set the url in the request to an invalid value (empty url).
274 newRequest.setURL(WebKit::WebURL());
275 return;
276 }
253 277
254 if (!IsProtocolSupportedForMedia(new_url)) { 278 if (!IsProtocolSupportedForMedia(newRequest.url())) {
279 // Set the url in the request to an invalid value (empty url).
280 newRequest.setURL(WebKit::WebURL());
255 DoneStart(net::ERR_ADDRESS_INVALID); 281 DoneStart(net::ERR_ADDRESS_INVALID);
256 Stop(); 282 Stop();
257 return false; 283 return;
258 } 284 }
259 return true; 285
286 url_loader_.reset(loader);
287 url_ = newRequest.url();
260 } 288 }
261 289
262 void BufferedResourceLoader::OnReceivedResponse( 290 void BufferedResourceLoader::didSendData(
263 const webkit_glue::ResourceResponseInfo& info, 291 WebURLLoader* loader,
264 bool content_filtered) { 292 unsigned long long bytes_sent,
265 DCHECK(bridge_.get()); 293 unsigned long long total_bytes_to_be_sent) {
294 }
Alpha Left Google 2010/11/19 22:53:42 Add NOTIMPLEMENTED();
295
296 void BufferedResourceLoader::didReceiveResponse(
297 WebURLLoader* loader, const WebURLResponse& response) {
266 298
267 // The loader may have been stopped and |start_callback| is destroyed. 299 // The loader may have been stopped and |start_callback| is destroyed.
268 // In this case we shouldn't do anything. 300 // In this case we shouldn't do anything.
269 if (!start_callback_.get()) 301 if (!start_callback_.get())
270 return; 302 return;
271 303
272 // We make a strong assumption that when we reach here we have either 304 // We make a strong assumption that when we reach here we have either
273 // received a response from HTTP/HTTPS protocol or the request was 305 // received a response from HTTP/HTTPS protocol or the request was
274 // successful (in particular range request). So we only verify the partial 306 // successful (in particular range request). So we only verify the partial
275 // response for HTTP and HTTPS protocol. 307 // response for HTTP and HTTPS protocol.
276 if (IsHttpProtocol(url_)) { 308 if (IsHttpProtocol(url_)) {
277 int error = net::OK; 309 int error = net::OK;
278 if (!info.headers) {
279 // We expect to receive headers because this is a HTTP or HTTPS protocol,
280 // if not report failure.
281 error = net::ERR_INVALID_RESPONSE;
282 } else {
283 if (info.headers->response_code() == kHttpPartialContent)
284 partial_response_ = true;
285 310
286 if (range_requested_ && partial_response_) { 311 if (response.httpStatusCode() == kHttpPartialContent)
287 // If we have verified the partial response and it is correct, we will 312 partial_response_ = true;
288 // return net::OK. 313
289 if (!VerifyPartialResponse(info)) 314 if (range_requested_ && partial_response_) {
315 // If we have verified the partial response and it is correct, we will
316 // return net::OK.
317 if (!VerifyPartialResponse(response))
290 error = net::ERR_INVALID_RESPONSE; 318 error = net::ERR_INVALID_RESPONSE;
291 } else if (info.headers->response_code() != kHttpOK) { 319 } else if (response.httpStatusCode() != kHttpOK) {
292 // We didn't request a range but server didn't reply with "200 OK". 320 // We didn't request a range but server didn't reply with "200 OK".
293 error = net::ERR_FAILED; 321 error = net::ERR_FAILED;
294 }
295 } 322 }
296 323
297 if (error != net::OK) { 324 if (error != net::OK) {
298 DoneStart(error); 325 DoneStart(error);
299 Stop(); 326 Stop();
300 return; 327 return;
301 } 328 }
302 } else { 329 } else {
303 // For any protocol other than HTTP and HTTPS, assume range request is 330 // For any protocol other than HTTP and HTTPS, assume range request is
304 // always fulfilled. 331 // always fulfilled.
305 partial_response_ = range_requested_; 332 partial_response_ = range_requested_;
306 } 333 }
307 334
308 // |info.content_length| can be -1, in that case |content_length_| is 335 // Expected content length can be -1, in that case |content_length_| is
309 // not specified and this is a streaming response. 336 // not specified and this is a streaming response.
310 content_length_ = info.content_length; 337 content_length_ = response.expectedContentLength();
311 338
312 // If we have not requested a range, then the size of the instance is equal 339 // If we have not requested a range, then the size of the instance is equal
313 // to the content length. 340 // to the content length.
314 if (!partial_response_) 341 if (!partial_response_)
315 instance_size_ = content_length_; 342 instance_size_ = content_length_;
316 343
317 // Calls with a successful response. 344 // Calls with a successful response.
318 DoneStart(net::OK); 345 DoneStart(net::OK);
319 } 346 }
320 347
321 void BufferedResourceLoader::OnReceivedData(const char* data, int len) { 348 void BufferedResourceLoader::didReceiveData(
322 DCHECK(bridge_.get()); 349 WebURLLoader* loader, const char* data, int data_length) {
350 DCHECK(!completed_);
351 DCHECK(data_length > 0);
Alpha Left Google 2010/11/19 22:53:42 DCHECK_GT(data_length, 0);
323 352
324 // If this loader has been stopped, |buffer_| would be destroyed. 353 // If this loader has been stopped, |buffer_| would be destroyed.
325 // In this case we shouldn't do anything. 354 // In this case we shouldn't do anything.
326 if (!buffer_.get()) 355 if (!buffer_.get())
327 return; 356 return;
328 357
329 // Writes more data to |buffer_|. 358 // Writes more data to |buffer_|.
330 buffer_->Append(reinterpret_cast<const uint8*>(data), len); 359 buffer_->Append(reinterpret_cast<const uint8*>(data), data_length);
331 360
332 // If there is an active read request, try to fulfill the request. 361 // If there is an active read request, try to fulfill the request.
333 if (HasPendingRead() && CanFulfillRead()) { 362 if (HasPendingRead() && CanFulfillRead()) {
334 ReadInternal(); 363 ReadInternal();
335 } else if (!defer_allowed_) { 364 } else if (!defer_allowed_) {
336 // If we're not allowed to defer, slide the buffer window forward instead 365 // If we're not allowed to defer, slide the buffer window forward instead
337 // of deferring. 366 // of deferring.
338 if (buffer_->forward_bytes() > buffer_->forward_capacity()) { 367 if (buffer_->forward_bytes() > buffer_->forward_capacity()) {
339 size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity(); 368 size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity();
340 bool success = buffer_->Seek(excess); 369 bool success = buffer_->Seek(excess);
341 DCHECK(success); 370 DCHECK(success);
342 offset_ += first_offset_ + excess; 371 offset_ += first_offset_ + excess;
343 } 372 }
344 } 373 }
345 374
346 // At last see if the buffer is full and we need to defer the downloading. 375 // At last see if the buffer is full and we need to defer the downloading.
347 EnableDeferIfNeeded(); 376 EnableDeferIfNeeded();
348 377
349 // Notify that we have received some data. 378 // Notify that we have received some data.
350 NotifyNetworkEvent(); 379 NotifyNetworkEvent();
351 } 380 }
352 381
353 void BufferedResourceLoader::OnCompletedRequest( 382 void BufferedResourceLoader::didDownloadData(
354 const URLRequestStatus& status, 383 WebKit::WebURLLoader* loader, int dataLength) {
355 const std::string& security_info, 384 }
Alpha Left Google 2010/11/19 22:53:42 Use NOTIMPLEMENTED(); instead.
356 const base::Time& completion_time) {
357 DCHECK(bridge_.get());
358 385
359 // Saves the information that the request has completed. 386 void BufferedResourceLoader::didReceiveCachedMetadata(
387 WebURLLoader* loader, const char* data, int data_length) {
388 DCHECK(!completed_);
Alpha Left Google 2010/11/19 22:53:42 Use NOTIMPLEMENTED(); instead.
389 DCHECK(data_length > 0);
390 }
391
392 void BufferedResourceLoader::didFinishLoading(
393 WebURLLoader* loader, double finishTime) {
394 DCHECK(!completed_);
360 completed_ = true; 395 completed_ = true;
361 396
362 // If there is a start callback, calls it. 397 // If there is a start callback, calls it.
363 if (start_callback_.get()) { 398 if (start_callback_.get()) {
364 DoneStart(status.os_error()); 399 DoneStart(net::OK);
365 } 400 }
366 401
367 // If there is a pending read but the request has ended, returns with what 402 // If there is a pending read but the request has ended, returns with what
368 // we have. 403 // we have.
369 if (HasPendingRead()) { 404 if (HasPendingRead()) {
370 // Make sure we have a valid buffer before we satisfy a read request. 405 // Make sure we have a valid buffer before we satisfy a read request.
371 DCHECK(buffer_.get()); 406 DCHECK(buffer_.get());
372 407
373 if (status.is_success()) { 408 // Try to fulfill with what is in the buffer.
374 // Try to fulfill with what is in the buffer. 409 if (CanFulfillRead())
375 if (CanFulfillRead()) 410 ReadInternal();
376 ReadInternal(); 411 else
377 else 412 DoneRead(net::ERR_CACHE_MISS);
378 DoneRead(net::ERR_CACHE_MISS);
379 } else {
380 // If the request has failed, then fail the read.
381 DoneRead(net::ERR_FAILED);
382 }
383 } 413 }
384 414
385 // There must not be any outstanding read request. 415 // There must not be any outstanding read request.
386 DCHECK(!HasPendingRead()); 416 DCHECK(!HasPendingRead());
387 417
388 // Notify that network response is completed. 418 // Notify that network response is completed.
389 NotifyNetworkEvent(); 419 NotifyNetworkEvent();
390 420
391 // We incremented the reference count when the loader was started. We balance 421 url_loader_.reset();
392 // that reference here so that we get destroyed. This is also the only safe
393 // place to destroy the ResourceLoaderBridge.
394 bridge_.reset();
395 Release(); 422 Release();
396 } 423 }
397 424
425 void BufferedResourceLoader::didFail(
426 WebURLLoader* loader,
427 const WebURLError& error) {
428 DCHECK(!completed_);
429 completed_ = true;
430
431 // If there is a start callback, calls it.
432 if (start_callback_.get()) {
433 DoneStart(error.reason);
434 }
435
436 // If there is a pending read but the request failed, return with the
437 // reason for the error.
438 if (HasPendingRead()) {
439 DoneRead(error.reason);
440 }
441
442 // Notify that network response is completed.
443 NotifyNetworkEvent();
444
445 url_loader_.reset();
446 Release();
447 }
448
398 ///////////////////////////////////////////////////////////////////////////// 449 /////////////////////////////////////////////////////////////////////////////
399 // BufferedResourceLoader, private 450 // BufferedResourceLoader, private
400 void BufferedResourceLoader::EnableDeferIfNeeded() { 451 void BufferedResourceLoader::EnableDeferIfNeeded() {
401 if (!defer_allowed_) 452 if (!defer_allowed_)
402 return; 453 return;
403 454
404 if (!deferred_ && 455 if (!deferred_ &&
405 buffer_->forward_bytes() >= buffer_->forward_capacity()) { 456 buffer_->forward_bytes() >= buffer_->forward_capacity()) {
406 deferred_ = true; 457 deferred_ = true;
407 458
408 if (bridge_.get()) 459 if (url_loader_.get())
409 bridge_->SetDefersLoading(true); 460 url_loader_->setDefersLoading(true);
410 461
411 NotifyNetworkEvent(); 462 NotifyNetworkEvent();
412 } 463 }
413 } 464 }
414 465
415 void BufferedResourceLoader::DisableDeferIfNeeded() { 466 void BufferedResourceLoader::DisableDeferIfNeeded() {
416 if (deferred_ && 467 if (deferred_ &&
417 (!defer_allowed_ || 468 (!defer_allowed_ ||
418 buffer_->forward_bytes() < buffer_->forward_capacity() / 2)) { 469 buffer_->forward_bytes() < buffer_->forward_capacity() / 2)) {
419 deferred_ = false; 470 deferred_ = false;
420 471
421 if (bridge_.get()) 472 if (url_loader_.get())
422 bridge_->SetDefersLoading(false); 473 url_loader_->setDefersLoading(false);
423 474
424 NotifyNetworkEvent(); 475 NotifyNetworkEvent();
425 } 476 }
426 } 477 }
427 478
428 bool BufferedResourceLoader::CanFulfillRead() { 479 bool BufferedResourceLoader::CanFulfillRead() {
429 // If we are reading too far in the backward direction. 480 // If we are reading too far in the backward direction.
430 if (first_offset_ < 0 && 481 if (first_offset_ < 0 &&
431 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) 482 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0)
432 return false; 483 return false;
(...skipping 40 matching lines...)
473 524
474 // Then do the read. 525 // Then do the read.
475 int read = static_cast<int>(buffer_->Read(read_buffer_, read_size_)); 526 int read = static_cast<int>(buffer_->Read(read_buffer_, read_size_));
476 offset_ += first_offset_ + read; 527 offset_ += first_offset_ + read;
477 528
478 // And report with what we have read. 529 // And report with what we have read.
479 DoneRead(read); 530 DoneRead(read);
480 } 531 }
481 532
482 bool BufferedResourceLoader::VerifyPartialResponse( 533 bool BufferedResourceLoader::VerifyPartialResponse(
483 const ResourceResponseInfo& info) { 534 const WebURLResponse& response) {
484 int64 first_byte_position, last_byte_position, instance_size; 535 int first_byte_position, last_byte_position, instance_size;
485 if (!info.headers->GetContentRange(&first_byte_position, 536
486 &last_byte_position, 537 if (!ReadContentRanges(response,
487 &instance_size)) { 538 &first_byte_position,
539 &last_byte_position,
540 &instance_size)) {
488 return false; 541 return false;
489 } 542 }
490 543
491 if (instance_size != kPositionNotSpecified) 544 if (instance_size != kPositionNotSpecified) {
492 instance_size_ = instance_size; 545 instance_size_ = instance_size;
546 }
493 547
494 if (first_byte_position_ != -1 && 548 if (first_byte_position_ != kPositionNotSpecified &&
495 first_byte_position_ != first_byte_position) { 549 first_byte_position_ != first_byte_position) {
496 return false; 550 return false;
497 } 551 }
498 552
499 // TODO(hclam): I should also check |last_byte_position|, but since 553 // TODO(hclam): I should also check |last_byte_position|, but since
500 // we will never make such a request that it is ok to leave it unimplemented. 554 // we will never make such a request that it is ok to leave it unimplemented.
501 return true; 555 return true;
502 } 556 }
503 557
558 bool BufferedResourceLoader::ReadContentRanges(
Alpha Left Google 2010/11/19 22:53:42 Instead of adding this method what about use ReadC
559 const WebURLResponse& response,
560 int* content_range_lower_bound,
561 int* content_range_upper_bound,
562 int* content_range_instance_size) {
563
564 std::string content_range = response.httpHeaderField("Content-Range").utf8();
565 if (content_range.empty()) {
566 content_range = response.httpHeaderField("Range").utf8();
567 }
568
569 if (content_range.empty()) {
570 DLOG(WARNING) << "Failed to read content range from response.";
571 return false;
572 }
573
574 size_t byte_range_lower_bound_start_offset = content_range.find(" ");
575 if (byte_range_lower_bound_start_offset == std::string::npos) {
576 return false;
577 }
578
579 // Skip over the initial space.
580 byte_range_lower_bound_start_offset++;
581
582 // Find the lower bound.
583 size_t byte_range_lower_bound_end_offset =
584 content_range.find("-", byte_range_lower_bound_start_offset);
585 if (byte_range_lower_bound_end_offset == std::string::npos) {
586 return false;
587 }
588
589 size_t byte_range_lower_bound_characters =
590 byte_range_lower_bound_end_offset - byte_range_lower_bound_start_offset;
591 std::string byte_range_lower_bound =
592 content_range.substr(byte_range_lower_bound_start_offset,
593 byte_range_lower_bound_characters);
594
595 // Find the upper bound.
596 size_t byte_range_upper_bound_start_offset =
597 byte_range_lower_bound_end_offset + 1;
598
599 size_t byte_range_upper_bound_end_offset =
600 content_range.find("/", byte_range_upper_bound_start_offset);
601 if (byte_range_upper_bound_end_offset == std::string::npos) {
602 return false;
603 }
604
605 size_t byte_range_upper_bound_characters =
606 byte_range_upper_bound_end_offset - byte_range_upper_bound_start_offset;
607 std::string byte_range_upper_bound =
608 content_range.substr(byte_range_upper_bound_start_offset,
609 byte_range_upper_bound_characters);
610
611 // Find the instance size.
612 size_t byte_range_instance_size_start_offset =
613 byte_range_upper_bound_end_offset + 1;
614
615 size_t byte_range_instance_size_end_offset =
616 content_range.length();
617
618 size_t byte_range_instance_size_characters =
619 byte_range_instance_size_end_offset -
620 byte_range_instance_size_start_offset;
621 std::string byte_range_instance_size =
622 content_range.substr(byte_range_instance_size_start_offset,
623 byte_range_instance_size_characters);
624
625 if (!base::StringToInt(byte_range_lower_bound, content_range_lower_bound))
626 return false;
627 if (!base::StringToInt(byte_range_upper_bound, content_range_upper_bound))
628 return false;
629 if (!base::StringToInt(byte_range_instance_size, content_range_instance_size))
630 return false;
631 return true;
632 }
633
634 std::string BufferedResourceLoader::GenerateHeaders(
635 int64 first_byte_position, int64 last_byte_position) {
636 // Construct the value for the range header.
637 std::string header;
638 if (first_byte_position > kPositionNotSpecified &&
639 last_byte_position > kPositionNotSpecified) {
640 if (first_byte_position <= last_byte_position) {
641 header = base::StringPrintf("bytes=%" PRId64 "-%" PRId64,
642 first_byte_position,
643 last_byte_position);
644 }
645 } else if (first_byte_position > kPositionNotSpecified) {
646 header = base::StringPrintf("bytes=%" PRId64 "-",
647 first_byte_position);
648 } else if (last_byte_position > kPositionNotSpecified) {
649 NOTIMPLEMENTED() << "Suffix range not implemented";
650 }
651 return header;
652 }
653
504 void BufferedResourceLoader::DoneRead(int error) { 654 void BufferedResourceLoader::DoneRead(int error) {
505 read_callback_->RunWithParams(Tuple1<int>(error)); 655 read_callback_->RunWithParams(Tuple1<int>(error));
506 read_callback_.reset(); 656 read_callback_.reset();
507 read_position_ = 0; 657 read_position_ = 0;
508 read_size_ = 0; 658 read_size_ = 0;
509 read_buffer_ = NULL; 659 read_buffer_ = NULL;
510 first_offset_ = 0; 660 first_offset_ = 0;
511 last_offset_ = 0; 661 last_offset_ = 0;
512 } 662 }
513 663
514 void BufferedResourceLoader::DoneStart(int error) { 664 void BufferedResourceLoader::DoneStart(int error) {
515 start_callback_->RunWithParams(Tuple1<int>(error)); 665 start_callback_->RunWithParams(Tuple1<int>(error));
516 start_callback_.reset(); 666 start_callback_.reset();
517 } 667 }
518 668
519 void BufferedResourceLoader::NotifyNetworkEvent() { 669 void BufferedResourceLoader::NotifyNetworkEvent() {
520 if (event_callback_.get()) 670 if (event_callback_.get())
521 event_callback_->Run(); 671 event_callback_->Run();
522 } 672 }
523 673
524 ///////////////////////////////////////////////////////////////////////////// 674 /////////////////////////////////////////////////////////////////////////////
525 // BufferedDataSource 675 // BufferedDataSource
526 BufferedDataSource::BufferedDataSource( 676 BufferedDataSource::BufferedDataSource(
527 MessageLoop* render_loop, 677 MessageLoop* render_loop,
528 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) 678 WebFrame* frame)
529 : total_bytes_(kPositionNotSpecified), 679 : total_bytes_(kPositionNotSpecified),
530 loaded_(false), 680 loaded_(false),
531 streaming_(false), 681 streaming_(false),
682 frame_(frame),
532 single_origin_(true), 683 single_origin_(true),
533 bridge_factory_(bridge_factory),
534 loader_(NULL), 684 loader_(NULL),
535 network_activity_(false), 685 network_activity_(false),
536 initialize_callback_(NULL), 686 initialize_callback_(NULL),
537 read_callback_(NULL), 687 read_callback_(NULL),
538 read_position_(0), 688 read_position_(0),
539 read_size_(0), 689 read_size_(0),
540 read_buffer_(NULL), 690 read_buffer_(NULL),
541 read_attempts_(0), 691 read_attempts_(0),
542 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]), 692 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]),
543 intermediate_read_buffer_size_(kInitialReadBufferSize), 693 intermediate_read_buffer_size_(kInitialReadBufferSize),
544 render_loop_(render_loop), 694 render_loop_(render_loop),
545 stop_signal_received_(false), 695 stop_signal_received_(false),
546 stopped_on_render_loop_(false), 696 stopped_on_render_loop_(false),
547 media_is_paused_(true), 697 media_is_paused_(true),
548 using_range_request_(true) { 698 using_range_request_(true) {
549 } 699 }
550 700
551 BufferedDataSource::~BufferedDataSource() { 701 BufferedDataSource::~BufferedDataSource() {
552 } 702 }
553 703
554 // A factory method to create BufferedResourceLoader using the read parameters. 704 // A factory method to create BufferedResourceLoader using the read parameters.
555 // This method can be overrided to inject mock BufferedResourceLoader object 705 // This method can be overrided to inject mock BufferedResourceLoader object
556 // for testing purpose. 706 // for testing purpose.
557 BufferedResourceLoader* BufferedDataSource::CreateResourceLoader( 707 BufferedResourceLoader* BufferedDataSource::CreateResourceLoader(
558 int64 first_byte_position, int64 last_byte_position) { 708 int64 first_byte_position, int64 last_byte_position) {
559 DCHECK(MessageLoop::current() == render_loop_); 709 DCHECK(MessageLoop::current() == render_loop_);
560 710
561 return new BufferedResourceLoader(bridge_factory_.get(), url_, 711 return new BufferedResourceLoader(url_,
562 first_byte_position, 712 first_byte_position,
563 last_byte_position); 713 last_byte_position);
564 } 714 }
565 715
566 // This method simply returns kTimeoutMilliseconds. The purpose of this 716 // This method simply returns kTimeoutMilliseconds. The purpose of this
567 // method is to be overidded so as to provide a different timeout value 717 // method is to be overidded so as to provide a different timeout value
568 // for testing purpose. 718 // for testing purpose.
569 base::TimeDelta BufferedDataSource::GetTimeoutMilliseconds() { 719 base::TimeDelta BufferedDataSource::GetTimeoutMilliseconds() {
570 return base::TimeDelta::FromMilliseconds(kTimeoutMilliseconds); 720 return base::TimeDelta::FromMilliseconds(kTimeoutMilliseconds);
571 } 721 }
(...skipping 79 matching lines...)
651 DCHECK(MessageLoop::current() == render_loop_); 801 DCHECK(MessageLoop::current() == render_loop_);
652 return single_origin_; 802 return single_origin_;
653 } 803 }
654 804
655 void BufferedDataSource::Abort() { 805 void BufferedDataSource::Abort() {
656 DCHECK(MessageLoop::current() == render_loop_); 806 DCHECK(MessageLoop::current() == render_loop_);
657 807
658 // If we are told to abort, immediately return from any pending read 808 // If we are told to abort, immediately return from any pending read
659 // with an error. 809 // with an error.
660 if (read_callback_.get()) { 810 if (read_callback_.get()) {
661 {
662 AutoLock auto_lock(lock_); 811 AutoLock auto_lock(lock_);
663 DoneRead_Locked(net::ERR_FAILED); 812 DoneRead_Locked(net::ERR_FAILED);
664 }
665 CleanupTask();
666 } 813 }
814
815 CleanupTask();
816 frame_ = NULL;
667 } 817 }
668 818
669 ///////////////////////////////////////////////////////////////////////////// 819 /////////////////////////////////////////////////////////////////////////////
670 // BufferedDataSource, render thread tasks 820 // BufferedDataSource, render thread tasks
671 void BufferedDataSource::InitializeTask() { 821 void BufferedDataSource::InitializeTask() {
672 DCHECK(MessageLoop::current() == render_loop_); 822 DCHECK(MessageLoop::current() == render_loop_);
673 DCHECK(!loader_.get()); 823 DCHECK(!loader_.get());
674 DCHECK(!stopped_on_render_loop_); 824 DCHECK(!stopped_on_render_loop_);
675 825
676 // Kick starts the watch dog task that will handle connection timeout. 826 // Kick starts the watch dog task that will handle connection timeout.
677 // We run the watch dog 2 times faster the actual timeout so as to catch 827 // We run the watch dog 2 times faster the actual timeout so as to catch
678 // the timeout more accurately. 828 // the timeout more accurately.
679 watch_dog_timer_.Start( 829 watch_dog_timer_.Start(
680 GetTimeoutMilliseconds() / 2, 830 GetTimeoutMilliseconds() / 2,
681 this, 831 this,
682 &BufferedDataSource::WatchDogTask); 832 &BufferedDataSource::WatchDogTask);
683 833
684 if (IsHttpProtocol(url_)) { 834 if (IsHttpProtocol(url_)) {
685 // Fetch only first 1024 bytes as this usually covers the header portion 835 // Fetch only first 1024 bytes as this usually covers the header portion
686 // of a media file that gives enough information about the codecs, etc. 836 // of a media file that gives enough information about the codecs, etc.
687 // This also serve as a probe to determine server capability to serve 837 // This also serve as a probe to determine server capability to serve
688 // range request. 838 // range request.
689 // TODO(hclam): Do some experiments for the best approach. 839 // TODO(hclam): Do some experiments for the best approach.
690 loader_ = CreateResourceLoader(0, 1024); 840 loader_ = CreateResourceLoader(0, 1024);
691 loader_->Start( 841 loader_->Start(
692 NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), 842 NewCallback(this, &BufferedDataSource::HttpInitialStartCallback),
693 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); 843 NewCallback(this, &BufferedDataSource::NetworkEventCallback),
844 frame_);
694 } else { 845 } else {
695 // For all other protocols, assume they support range request. We fetch 846 // For all other protocols, assume they support range request. We fetch
696 // the full range of the resource to obtain the instance size because 847 // the full range of the resource to obtain the instance size because
697 // we won't be served HTTP headers. 848 // we won't be served HTTP headers.
698 loader_ = CreateResourceLoader(-1, -1); 849 loader_ = CreateResourceLoader(-1, -1);
699 loader_->Start( 850 loader_->Start(
700 NewCallback(this, &BufferedDataSource::NonHttpInitialStartCallback), 851 NewCallback(this, &BufferedDataSource::NonHttpInitialStartCallback),
701 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); 852 NewCallback(this, &BufferedDataSource::NetworkEventCallback),
853 frame_);
702 } 854 }
703 } 855 }
704 856
705 void BufferedDataSource::ReadTask( 857 void BufferedDataSource::ReadTask(
706 int64 position, int read_size, uint8* buffer, 858 int64 position, int read_size, uint8* buffer,
707 media::DataSource::ReadCallback* read_callback) { 859 media::DataSource::ReadCallback* read_callback) {
708 DCHECK(MessageLoop::current() == render_loop_); 860 DCHECK(MessageLoop::current() == render_loop_);
709 861
710 // If CleanupTask() was executed we should return immediately. We check this 862 // If CleanupTask() was executed we should return immediately. We check this
711 // variable to prevent doing any actual work after clean up was done. We do 863 // variable to prevent doing any actual work after clean up was done. We do
(...skipping 56 matching lines...)
768 return; 920 return;
769 921
770 // If there's no outstanding read then return early. 922 // If there's no outstanding read then return early.
771 if (!read_callback_.get()) 923 if (!read_callback_.get())
772 return; 924 return;
773 925
774 loader_ = CreateResourceLoader(read_position_, -1); 926 loader_ = CreateResourceLoader(read_position_, -1);
775 loader_->SetAllowDefer(!media_is_paused_); 927 loader_->SetAllowDefer(!media_is_paused_);
776 loader_->Start( 928 loader_->Start(
777 NewCallback(this, &BufferedDataSource::PartialReadStartCallback), 929 NewCallback(this, &BufferedDataSource::PartialReadStartCallback),
778 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); 930 NewCallback(this, &BufferedDataSource::NetworkEventCallback),
931 frame_);
779 } 932 }
780 933
781 void BufferedDataSource::WatchDogTask() { 934 void BufferedDataSource::WatchDogTask() {
782 DCHECK(MessageLoop::current() == render_loop_); 935 DCHECK(MessageLoop::current() == render_loop_);
783 DCHECK(!stopped_on_render_loop_); 936 DCHECK(!stopped_on_render_loop_);
784 937
785 // We only care if there is an active read request. 938 // We only care if there is an active read request.
786 if (!read_callback_.get()) 939 if (!read_callback_.get())
787 return; 940 return;
788 941
(...skipping 10 matching lines...)
799 ++read_attempts_; 952 ++read_attempts_;
800 read_submitted_time_ = base::Time::Now(); 953 read_submitted_time_ = base::Time::Now();
801 954
802 // Stops the current loader and creates a new resource loader and 955 // Stops the current loader and creates a new resource loader and
803 // retry the request. 956 // retry the request.
804 loader_->Stop(); 957 loader_->Stop();
805 loader_ = CreateResourceLoader(read_position_, -1); 958 loader_ = CreateResourceLoader(read_position_, -1);
806 loader_->SetAllowDefer(!media_is_paused_); 959 loader_->SetAllowDefer(!media_is_paused_);
807 loader_->Start( 960 loader_->Start(
808 NewCallback(this, &BufferedDataSource::PartialReadStartCallback), 961 NewCallback(this, &BufferedDataSource::PartialReadStartCallback),
809 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); 962 NewCallback(this, &BufferedDataSource::NetworkEventCallback),
963 frame_);
810 } 964 }
811 965
812 void BufferedDataSource::SetPlaybackRateTask(float playback_rate) { 966 void BufferedDataSource::SetPlaybackRateTask(float playback_rate) {
813 DCHECK(MessageLoop::current() == render_loop_); 967 DCHECK(MessageLoop::current() == render_loop_);
814 DCHECK(loader_.get()); 968 DCHECK(loader_.get());
815 969
816 bool previously_paused = media_is_paused_; 970 bool previously_paused = media_is_paused_;
817 media_is_paused_ = (playback_rate == 0.0); 971 media_is_paused_ = (playback_rate == 0.0);
818 972
819 // Disallow deferring data when we are pausing, allow deferring data 973 // Disallow deferring data when we are pausing, allow deferring data
820 // when we resume playing. 974 // when we resume playing.
821 if (previously_paused && !media_is_paused_) { 975 if (previously_paused && !media_is_paused_) {
822 loader_->SetAllowDefer(true); 976 loader_->SetAllowDefer(true);
823 } else if (!previously_paused && media_is_paused_) { 977 } else if (!previously_paused && media_is_paused_) {
824 loader_->SetAllowDefer(false); 978 loader_->SetAllowDefer(false);
825 } 979 }
826 } 980 }
827 981
828 // This method is the place where actual read happens, |loader_| must be valid 982 // This method is the place where actual read happens, |loader_| must be valid
829 // prior to make this method call. 983 // prior to make this method call.
830 void BufferedDataSource::ReadInternal() { 984 void BufferedDataSource::ReadInternal() {
831 DCHECK(MessageLoop::current() == render_loop_); 985 DCHECK(MessageLoop::current() == render_loop_);
832 DCHECK(loader_.get()); 986 DCHECK(loader_);
833 987
834 // First we prepare the intermediate read buffer for BufferedResourceLoader 988 // First we prepare the intermediate read buffer for BufferedResourceLoader
835 // to write to. 989 // to write to.
836 if (read_size_ > intermediate_read_buffer_size_) { 990 if (read_size_ > intermediate_read_buffer_size_) {
837 intermediate_read_buffer_.reset(new uint8[read_size_]); 991 intermediate_read_buffer_.reset(new uint8[read_size_]);
838 } 992 }
839 993
840 // Perform the actual read with BufferedResourceLoader. 994 // Perform the actual read with BufferedResourceLoader.
841 loader_->Read(read_position_, read_size_, intermediate_read_buffer_.get(), 995 loader_->Read(read_position_, read_size_, intermediate_read_buffer_.get(),
842 NewCallback(this, &BufferedDataSource::ReadCallback)); 996 NewCallback(this, &BufferedDataSource::ReadCallback));
(...skipping 54 matching lines...)
897 loader_->Stop(); 1051 loader_->Stop();
898 } 1052 }
899 1053
900 if (error == net::ERR_INVALID_RESPONSE && using_range_request_) { 1054 if (error == net::ERR_INVALID_RESPONSE && using_range_request_) {
901 // Assuming that the Range header was causing the problem. Retry without 1055 // Assuming that the Range header was causing the problem. Retry without
902 // the Range header. 1056 // the Range header.
903 using_range_request_ = false; 1057 using_range_request_ = false;
904 loader_ = CreateResourceLoader(-1, -1); 1058 loader_ = CreateResourceLoader(-1, -1);
905 loader_->Start( 1059 loader_->Start(
906 NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), 1060 NewCallback(this, &BufferedDataSource::HttpInitialStartCallback),
907 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); 1061 NewCallback(this, &BufferedDataSource::NetworkEventCallback),
1062 frame_);
908 return; 1063 return;
909 } 1064 }
910 1065
911 // We need to prevent calling to filter host and running the callback if 1066 // We need to prevent calling to filter host and running the callback if
912 // we have received the stop signal. We need to lock down the whole callback 1067 // we have received the stop signal. We need to lock down the whole callback
913 // method to prevent bad things from happening. The reason behind this is 1068 // method to prevent bad things from happening. The reason behind this is
914 // that we cannot guarantee tasks on render thread have completely stopped 1069 // that we cannot guarantee tasks on render thread have completely stopped
915 // when we receive the Stop() method call. The only way to solve this is to 1070 // when we receive the Stop() method call. The only way to solve this is to
916 // let tasks on render thread to run but make sure they don't call outside 1071 // let tasks on render thread to run but make sure they don't call outside
917 // this object when Stop() method is ever called. Locking this method is safe 1072 // this object when Stop() method is ever called. Locking this method is safe
(...skipping 159 matching lines...)
1077 return; 1232 return;
1078 1233
1079 if (network_activity != network_activity_) { 1234 if (network_activity != network_activity_) {
1080 network_activity_ = network_activity; 1235 network_activity_ = network_activity;
1081 host()->SetNetworkActivity(network_activity); 1236 host()->SetNetworkActivity(network_activity);
1082 } 1237 }
1083 host()->SetBufferedBytes(buffered_last_byte_position + 1); 1238 host()->SetBufferedBytes(buffered_last_byte_position + 1);
1084 } 1239 }
1085 1240
1086 } // namespace webkit_glue 1241 } // namespace webkit_glue
OLDNEW

Powered by Google App Engine