Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(811)

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

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

Powered by Google App Engine
This is Rietveld 408576698