OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/glue/media/buffered_resource_loader.h" | 5 #include "webkit/glue/media/buffered_resource_loader.h" |
6 | 6 |
7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" | 10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" |
11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKitClient.h" | 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKitClient.h" |
12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" | 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" | 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" |
14 #include "webkit/glue/media/buffered_data_source.h" | |
acolwell GONE FROM CHROMIUM
2011/03/25 23:08:14
Do you still need this?
vrk (LEFT CHROMIUM)
2011/03/29 00:53:00
Nope! Removed :)
| |
14 #include "webkit/glue/multipart_response_delegate.h" | 15 #include "webkit/glue/multipart_response_delegate.h" |
15 #include "webkit/glue/webkit_glue.h" | 16 #include "webkit/glue/webkit_glue.h" |
16 | 17 |
17 using WebKit::WebFrame; | 18 using WebKit::WebFrame; |
18 using WebKit::WebString; | 19 using WebKit::WebString; |
19 using WebKit::WebURLError; | 20 using WebKit::WebURLError; |
20 using WebKit::WebURLLoader; | 21 using WebKit::WebURLLoader; |
21 using WebKit::WebURLRequest; | 22 using WebKit::WebURLRequest; |
22 using WebKit::WebURLResponse; | 23 using WebKit::WebURLResponse; |
23 using webkit_glue::MultipartResponseDelegate; | 24 using webkit_glue::MultipartResponseDelegate; |
(...skipping 19 matching lines...) Expand all Loading... | |
43 // number to be 2MB. | 44 // number to be 2MB. |
44 // TODO(hclam): determine a better value for this. | 45 // TODO(hclam): determine a better value for this. |
45 static const int kForwardWaitThreshold = 2 * kMegabyte; | 46 static const int kForwardWaitThreshold = 2 * kMegabyte; |
46 | 47 |
47 BufferedResourceLoader::BufferedResourceLoader( | 48 BufferedResourceLoader::BufferedResourceLoader( |
48 const GURL& url, | 49 const GURL& url, |
49 int64 first_byte_position, | 50 int64 first_byte_position, |
50 int64 last_byte_position) | 51 int64 last_byte_position) |
51 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), | 52 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), |
52 deferred_(false), | 53 deferred_(false), |
53 defer_allowed_(true), | 54 defer_strategy_(ReadThenDefer), |
54 completed_(false), | 55 completed_(false), |
55 range_requested_(false), | 56 range_requested_(false), |
56 partial_response_(false), | 57 partial_response_(false), |
57 url_(url), | 58 url_(url), |
58 first_byte_position_(first_byte_position), | 59 first_byte_position_(first_byte_position), |
59 last_byte_position_(last_byte_position), | 60 last_byte_position_(last_byte_position), |
60 single_origin_(true), | 61 single_origin_(true), |
61 start_callback_(NULL), | 62 start_callback_(NULL), |
62 offset_(0), | 63 offset_(0), |
63 content_length_(kPositionNotSpecified), | 64 content_length_(kPositionNotSpecified), |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
173 return; | 174 return; |
174 } | 175 } |
175 | 176 |
176 // Prepare the parameters. | 177 // Prepare the parameters. |
177 first_offset_ = static_cast<int>(read_position_ - offset_); | 178 first_offset_ = static_cast<int>(read_position_ - offset_); |
178 last_offset_ = first_offset_ + read_size_; | 179 last_offset_ = first_offset_ + read_size_; |
179 | 180 |
180 // If we can serve the request now, do the actual read. | 181 // If we can serve the request now, do the actual read. |
181 if (CanFulfillRead()) { | 182 if (CanFulfillRead()) { |
182 ReadInternal(); | 183 ReadInternal(); |
183 DisableDeferIfNeeded(); | 184 UpdateDeferBehavior(); |
184 return; | 185 return; |
185 } | 186 } |
186 | 187 |
188 // If you're deferred and you can't fulfill the read because you don't have | |
189 // enough data, you will never fulfill the read. | |
190 // Update defer behavior to re-enable deferring if need be. | |
191 UpdateDeferBehavior(); | |
192 | |
187 // If we expected the read request to be fulfilled later, returns | 193 // If we expected the read request to be fulfilled later, returns |
188 // immediately and let more data to flow in. | 194 // immediately and let more data to flow in. |
189 if (WillFulfillRead()) | 195 if (WillFulfillRead()) |
190 return; | 196 return; |
191 | 197 |
192 // Make a callback to report failure. | 198 // Make a callback to report failure. |
193 DoneRead(net::ERR_CACHE_MISS); | 199 DoneRead(net::ERR_CACHE_MISS); |
194 } | 200 } |
195 | 201 |
196 int64 BufferedResourceLoader::GetBufferedPosition() { | 202 int64 BufferedResourceLoader::GetBufferedPosition() { |
197 if (buffer_.get()) | 203 if (buffer_.get()) |
198 return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1; | 204 return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1; |
199 return kPositionNotSpecified; | 205 return kPositionNotSpecified; |
200 } | 206 } |
201 | 207 |
202 void BufferedResourceLoader::SetAllowDefer(bool is_allowed) { | |
203 defer_allowed_ = is_allowed; | |
204 DisableDeferIfNeeded(); | |
205 } | |
206 | |
207 int64 BufferedResourceLoader::content_length() { | 208 int64 BufferedResourceLoader::content_length() { |
208 return content_length_; | 209 return content_length_; |
209 } | 210 } |
210 | 211 |
211 int64 BufferedResourceLoader::instance_size() { | 212 int64 BufferedResourceLoader::instance_size() { |
212 return instance_size_; | 213 return instance_size_; |
213 } | 214 } |
214 | 215 |
215 bool BufferedResourceLoader::partial_response() { | 216 bool BufferedResourceLoader::partial_response() { |
216 return partial_response_; | 217 return partial_response_; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
327 | 328 |
328 // If this loader has been stopped, |buffer_| would be destroyed. | 329 // If this loader has been stopped, |buffer_| would be destroyed. |
329 // In this case we shouldn't do anything. | 330 // In this case we shouldn't do anything. |
330 if (!buffer_.get()) | 331 if (!buffer_.get()) |
331 return; | 332 return; |
332 | 333 |
333 // Writes more data to |buffer_|. | 334 // Writes more data to |buffer_|. |
334 buffer_->Append(reinterpret_cast<const uint8*>(data), data_length); | 335 buffer_->Append(reinterpret_cast<const uint8*>(data), data_length); |
335 | 336 |
336 // If there is an active read request, try to fulfill the request. | 337 // If there is an active read request, try to fulfill the request. |
337 if (HasPendingRead() && CanFulfillRead()) { | 338 if (HasPendingRead() && CanFulfillRead()) |
338 ReadInternal(); | 339 ReadInternal(); |
339 } else if (!defer_allowed_) { | |
340 // If we're not allowed to defer, slide the buffer window forward instead | |
341 // of deferring. | |
342 if (buffer_->forward_bytes() > buffer_->forward_capacity()) { | |
343 size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity(); | |
344 bool success = buffer_->Seek(excess); | |
345 DCHECK(success); | |
346 offset_ += first_offset_ + excess; | |
347 } | |
348 } | |
349 | 340 |
350 // At last see if the buffer is full and we need to defer the downloading. | 341 // At last see if the buffer is full and we need to defer the downloading. |
351 EnableDeferIfNeeded(); | 342 UpdateDeferBehavior(); |
343 | |
344 // Consume excess bytes from our in-memory buffer if necessary. | |
345 if (buffer_->forward_bytes() > buffer_->forward_capacity()) { | |
acolwell GONE FROM CHROMIUM
2011/03/25 23:08:14
This looks like a change in behavior. why is this
vrk (LEFT CHROMIUM)
2011/03/29 00:53:00
Ah I meant to tell you about this! Brief storytime
acolwell GONE FROM CHROMIUM
2011/03/29 05:52:03
Ok. I think I understand. It sounds reasonable to
| |
346 size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity(); | |
347 bool success = buffer_->Seek(excess); | |
348 DCHECK(success); | |
349 offset_ += first_offset_ + excess; | |
350 } | |
352 | 351 |
353 // Notify that we have received some data. | 352 // Notify that we have received some data. |
354 NotifyNetworkEvent(); | 353 NotifyNetworkEvent(); |
355 } | 354 } |
356 | 355 |
357 void BufferedResourceLoader::didDownloadData( | 356 void BufferedResourceLoader::didDownloadData( |
358 WebKit::WebURLLoader* loader, | 357 WebKit::WebURLLoader* loader, |
359 int dataLength) { | 358 int dataLength) { |
360 NOTIMPLEMENTED(); | 359 NOTIMPLEMENTED(); |
361 } | 360 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 url_loader_.reset(); | 423 url_loader_.reset(); |
425 Release(); | 424 Release(); |
426 } | 425 } |
427 | 426 |
428 bool BufferedResourceLoader::HasSingleOrigin() const { | 427 bool BufferedResourceLoader::HasSingleOrigin() const { |
429 return single_origin_; | 428 return single_origin_; |
430 } | 429 } |
431 | 430 |
432 ///////////////////////////////////////////////////////////////////////////// | 431 ///////////////////////////////////////////////////////////////////////////// |
433 // Helper methods. | 432 // Helper methods. |
434 void BufferedResourceLoader::EnableDeferIfNeeded() { | 433 void BufferedResourceLoader::UpdateDeferBehavior() { |
435 if (!defer_allowed_) | 434 if ((deferred_ && ShouldDisableDefer()) || |
436 return; | 435 (!deferred_ && ShouldEnableDefer())) { |
437 | 436 bool eventOccurred = ToggleDeferring(); |
438 if (!deferred_ && | 437 if (eventOccurred) |
439 buffer_->forward_bytes() >= buffer_->forward_capacity()) { | 438 NotifyNetworkEvent(); |
440 deferred_ = true; | |
441 | |
442 if (url_loader_.get()) | |
443 url_loader_->setDefersLoading(true); | |
444 | |
445 NotifyNetworkEvent(); | |
446 } | 439 } |
447 } | 440 } |
448 | 441 |
449 void BufferedResourceLoader::DisableDeferIfNeeded() { | 442 void BufferedResourceLoader::SetDeferStrategy(DeferStrategy strategy) { |
450 if (deferred_ && | 443 defer_strategy_ = strategy; |
451 (!defer_allowed_ || | 444 } |
452 buffer_->forward_bytes() < buffer_->forward_capacity() / 2)) { | |
453 deferred_ = false; | |
454 | 445 |
455 if (url_loader_.get()) | 446 bool BufferedResourceLoader::ShouldEnableDefer() { |
456 url_loader_->setDefersLoading(false); | 447 // If we're already deferring, then enabling makes no sense. |
448 if (deferred_) | |
449 return false; | |
457 | 450 |
458 NotifyNetworkEvent(); | 451 switch(defer_strategy_) { |
452 // Never defer at all, so never enable defer. | |
453 case NeverDefer: | |
454 return false; | |
455 | |
456 // Defer if nothing is being requested. | |
457 case ReadThenDefer: | |
458 return !read_callback_.get(); | |
459 | |
460 // Defer if we've reached the max capacity of the threshold. | |
461 case ThresholdDefer: | |
462 return buffer_->forward_bytes() >= buffer_->forward_capacity(); | |
459 } | 463 } |
464 // Otherwise no longer defer. | |
465 return false; | |
466 } | |
467 | |
468 bool BufferedResourceLoader::ShouldDisableDefer() { | |
469 // If we're not deferring, then disabling makes no sense. | |
470 if (!deferred_) | |
471 return false; | |
472 | |
473 switch(defer_strategy_) { | |
474 // Always disable deferring. | |
475 case NeverDefer: | |
476 return true; | |
477 | |
478 // We have an outstanding read request, and we have not buffered enoug | |
acolwell GONE FROM CHROMIUM
2011/03/25 23:08:14
enoug -> enough
vrk (LEFT CHROMIUM)
2011/03/29 00:53:00
Done.
| |
479 // yet to fulfill the request; disable defer to get more data. | |
480 case ReadThenDefer: { | |
481 size_t amount_buffered = buffer_->forward_bytes(); | |
482 size_t amount_to_read = static_cast<size_t>(read_size_); | |
483 return read_callback_.get() && amount_buffered < amount_to_read; | |
484 } | |
485 | |
486 // We have less than half the capacity of our threshold, so | |
487 // disable defer to get more data. | |
488 case ThresholdDefer: { | |
489 size_t amount_buffered = buffer_->forward_bytes(); | |
490 size_t half_capacity = buffer_->forward_capacity() / 2; | |
491 return amount_buffered < half_capacity; | |
492 } | |
493 } | |
494 | |
495 // Otherwise keep deferring. | |
496 return false; | |
497 } | |
498 | |
499 bool BufferedResourceLoader::ToggleDeferring() { | |
500 bool newDeferSetting = !deferred_; | |
501 deferred_ = newDeferSetting; | |
acolwell GONE FROM CHROMIUM
2011/03/25 23:08:14
deferred_ = !deferred_
vrk (LEFT CHROMIUM)
2011/03/29 00:53:00
Done.
| |
502 if (url_loader_.get()) { | |
503 url_loader_->setDefersLoading(newDeferSetting); | |
acolwell GONE FROM CHROMIUM
2011/03/25 23:08:14
deferred_
vrk (LEFT CHROMIUM)
2011/03/29 00:53:00
Done.
| |
504 return true; | |
505 } | |
506 return false; | |
460 } | 507 } |
461 | 508 |
462 bool BufferedResourceLoader::CanFulfillRead() { | 509 bool BufferedResourceLoader::CanFulfillRead() { |
463 // If we are reading too far in the backward direction. | 510 // If we are reading too far in the backward direction. |
464 if (first_offset_ < 0 && | 511 if (first_offset_ < 0 && |
465 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) | 512 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) |
466 return false; | 513 return false; |
467 | 514 |
468 // If the start offset is too far ahead. | 515 // If the start offset is too far ahead. |
469 if (first_offset_ >= static_cast<int>(buffer_->forward_bytes())) | 516 if (first_offset_ >= static_cast<int>(buffer_->forward_bytes())) |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
573 start_callback_->RunWithParams(Tuple1<int>(error)); | 620 start_callback_->RunWithParams(Tuple1<int>(error)); |
574 start_callback_.reset(); | 621 start_callback_.reset(); |
575 } | 622 } |
576 | 623 |
577 void BufferedResourceLoader::NotifyNetworkEvent() { | 624 void BufferedResourceLoader::NotifyNetworkEvent() { |
578 if (event_callback_.get()) | 625 if (event_callback_.get()) |
579 event_callback_->Run(); | 626 event_callback_->Run(); |
580 } | 627 } |
581 | 628 |
582 } // namespace webkit_glue | 629 } // namespace webkit_glue |
OLD | NEW |