diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-03 01:49:16 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-03 01:49:16 +0000 |
commit | 8f2bf64884944e8b770852240e34e79f117acbb6 (patch) | |
tree | e7235339bc556dc5f933b75578cb12ca8f2ce905 /webkit/glue/media/buffered_data_source.cc | |
parent | ebc34fab52eabbb680eee966bb10e8f8a8cbd845 (diff) | |
download | chromium_src-8f2bf64884944e8b770852240e34e79f117acbb6.zip chromium_src-8f2bf64884944e8b770852240e34e79f117acbb6.tar.gz chromium_src-8f2bf64884944e8b770852240e34e79f117acbb6.tar.bz2 |
Revert 68094 - Refactoring BufferedDataSource to work with WebURLLoader instead of a MediaResourceLoaderBridge.
One thing to notice is that both buffered_data_source_unittest and simple_data_source_unittest need to have a way to inject a MockWebURLLoader into the BufferedResourceLoader and the SimpleDataSource. In order to make sure a new one is not created during a Start(), I introduced the function SetURLLoaderForTest and keep_test_loader flag.
Patch by annacc@chromium.org:
http://codereview.chromium.org/3863002/
BUG=16751
TEST=src/xcodebuild/Debug/test_shell_tests --gtest_filter=Buffered*
src/xcodebuild/Debug/test_shell_tests --gtest_filter=Simple*
src/webkit/tools/layout_tests/run_webkit_tests.sh --debug media
webkit/tools/layout_tests/run_webkit_tests.sh --debug http/tests/media
TBR=scherkus@chromium.org
Review URL: http://codereview.chromium.org/5619002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68126 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/media/buffered_data_source.cc')
-rw-r--r-- | webkit/glue/media/buffered_data_source.cc | 309 |
1 files changed, 112 insertions, 197 deletions
diff --git a/webkit/glue/media/buffered_data_source.cc b/webkit/glue/media/buffered_data_source.cc index a82ce87..c864767 100644 --- a/webkit/glue/media/buffered_data_source.cc +++ b/webkit/glue/media/buffered_data_source.cc @@ -4,33 +4,19 @@ #include "base/callback.h" #include "base/compiler_specific.h" -#include "base/format_macros.h" #include "base/message_loop.h" #include "base/process_util.h" #include "base/stl_util-inl.h" -#include "base/string_number_conversions.h" #include "base/string_util.h" #include "media/base/filter_host.h" #include "media/base/media_format.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" -#include "third_party/WebKit/WebKit/chromium/public/WebKit.h" -#include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h" -#include "third_party/WebKit/WebKit/chromium/public/WebString.h" -#include "third_party/WebKit/WebKit/chromium/public/WebURLError.h" +#include "net/http/http_response_headers.h" #include "webkit/glue/media/buffered_data_source.h" -#include "webkit/glue/multipart_response_delegate.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/webmediaplayer_impl.h" -using WebKit::WebFrame; -using WebKit::WebString; -using WebKit::WebURLError; -using WebKit::WebURLLoader; -using WebKit::WebURLRequest; -using WebKit::WebURLResponse; -using webkit_glue::MultipartResponseDelegate; - namespace { const char kHttpScheme[] = "http"; @@ -84,10 +70,10 @@ bool IsDataProtocol(const GURL& url) { } // namespace namespace webkit_glue { - ///////////////////////////////////////////////////////////////////////////// // BufferedResourceLoader BufferedResourceLoader::BufferedResourceLoader( + webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory, const GURL& url, int64 first_byte_position, int64 last_byte_position) @@ -97,10 +83,12 @@ BufferedResourceLoader::BufferedResourceLoader( completed_(false), range_requested_(false), partial_response_(false), + bridge_factory_(bridge_factory), url_(url), first_byte_position_(first_byte_position), last_byte_position_(last_byte_position), start_callback_(NULL), + bridge_(NULL), offset_(0), content_length_(kPositionNotSpecified), instance_size_(kPositionNotSpecified), @@ -109,24 +97,20 @@ BufferedResourceLoader::BufferedResourceLoader( read_size_(0), read_buffer_(NULL), first_offset_(0), - last_offset_(0), - keep_test_loader_(false) { + last_offset_(0) { } BufferedResourceLoader::~BufferedResourceLoader() { - if (!completed_ && url_loader_.get()) - url_loader_->cancel(); } void BufferedResourceLoader::Start(net::CompletionCallback* start_callback, - NetworkEventCallback* event_callback, - WebFrame* frame) { + NetworkEventCallback* event_callback) { // Make sure we have not started. + DCHECK(!bridge_.get()); DCHECK(!start_callback_.get()); DCHECK(!event_callback_.get()); DCHECK(start_callback); DCHECK(event_callback); - CHECK(frame); start_callback_.reset(start_callback); event_callback_.reset(event_callback); @@ -138,26 +122,21 @@ void BufferedResourceLoader::Start(net::CompletionCallback* start_callback, offset_ = first_byte_position_; } + // Creates the bridge on render thread since we can only access + // ResourceDispatcher on this thread. + bridge_.reset( + bridge_factory_->CreateBridge( + url_, + net::LOAD_NORMAL, + first_byte_position_, + last_byte_position_)); + // Increment the reference count right before we start the request. This // reference will be release when this request has ended. AddRef(); - // Prepare the request. - WebURLRequest request(url_); - request.setHTTPHeaderField(WebString::fromUTF8("Range"), - WebString::fromUTF8(GenerateHeaders( - first_byte_position_, - last_byte_position_))); - frame->setReferrerForRequest(request, WebKit::WebURL()); - // TODO(annacc): we should be using createAssociatedURLLoader() instead? - frame->dispatchWillSendRequest(request); - - // This flag is for unittests as we don't want to reset |url_loader| - if (!keep_test_loader_) - url_loader_.reset(WebKit::webKitClient()->createURLLoader()); - - // Start the resource loading. - url_loader_->loadAsynchronously(request, this); + // And start the resource loading. + bridge_->Start(this); } void BufferedResourceLoader::Stop() { @@ -174,15 +153,14 @@ void BufferedResourceLoader::Stop() { // Destroy internal buffer. buffer_.reset(); - if (url_loader_.get()) { + if (bridge_.get()) { + // Cancel the request. This method call will cancel the request + // asynchronously. We may still get data or messages until we receive + // a response completed message. if (deferred_) - url_loader_->setDefersLoading(false); + bridge_->SetDefersLoading(false); deferred_ = false; - - if (!completed_) { - url_loader_->cancel(); - completed_ = true; - } + bridge_->Cancel(); } } @@ -253,47 +231,38 @@ void BufferedResourceLoader::SetAllowDefer(bool is_allowed) { DisableDeferIfNeeded(); } -void BufferedResourceLoader::SetURLLoaderForTest(WebURLLoader* mock_loader) { - url_loader_.reset(mock_loader); - keep_test_loader_ = true; -} - ///////////////////////////////////////////////////////////////////////////// -// BufferedResourceLoader, WebKit::WebURLLoaderClient implementations. -void BufferedResourceLoader::willSendRequest( - WebURLLoader* loader, - WebURLRequest& newRequest, - const WebURLResponse& redirectResponse) { +// BufferedResourceLoader, +// webkit_glue::ResourceLoaderBridge::Peer implementations +bool BufferedResourceLoader::OnReceivedRedirect( + const GURL& new_url, + const webkit_glue::ResourceResponseInfo& info, + bool* has_new_first_party_for_cookies, + GURL* new_first_party_for_cookies) { + DCHECK(bridge_.get()); + + // Save the new URL. + url_ = new_url; + // TODO(wtc): should we return a new first party for cookies URL? + *has_new_first_party_for_cookies = false; // The load may have been stopped and |start_callback| is destroyed. // In this case we shouldn't do anything. - if (!start_callback_.get()) { - // Set the url in the request to an invalid value (empty url). - newRequest.setURL(WebKit::WebURL()); - return; - } + if (!start_callback_.get()) + return true; - if (!IsProtocolSupportedForMedia(newRequest.url())) { - // Set the url in the request to an invalid value (empty url). - newRequest.setURL(WebKit::WebURL()); + if (!IsProtocolSupportedForMedia(new_url)) { DoneStart(net::ERR_ADDRESS_INVALID); Stop(); - return; + return false; } - - url_ = newRequest.url(); -} - -void BufferedResourceLoader::didSendData( - WebURLLoader* loader, - unsigned long long bytes_sent, - unsigned long long total_bytes_to_be_sent) { - NOTIMPLEMENTED(); + return true; } -void BufferedResourceLoader::didReceiveResponse( - WebURLLoader* loader, - const WebURLResponse& response) { +void BufferedResourceLoader::OnReceivedResponse( + const webkit_glue::ResourceResponseInfo& info, + bool content_filtered) { + DCHECK(bridge_.get()); // The loader may have been stopped and |start_callback| is destroyed. // In this case we shouldn't do anything. @@ -306,18 +275,23 @@ void BufferedResourceLoader::didReceiveResponse( // response for HTTP and HTTPS protocol. if (IsHttpProtocol(url_)) { int error = net::OK; - - if (response.httpStatusCode() == kHttpPartialContent) - partial_response_ = true; - - if (range_requested_ && partial_response_) { - // If we have verified the partial response and it is correct, we will - // return net::OK. - if (!VerifyPartialResponse(response)) - error = net::ERR_INVALID_RESPONSE; - } else if (response.httpStatusCode() != kHttpOK) { - // We didn't request a range but server didn't reply with "200 OK". - error = net::ERR_FAILED; + if (!info.headers) { + // We expect to receive headers because this is a HTTP or HTTPS protocol, + // if not report failure. + error = net::ERR_INVALID_RESPONSE; + } else { + if (info.headers->response_code() == kHttpPartialContent) + partial_response_ = true; + + if (range_requested_ && partial_response_) { + // If we have verified the partial response and it is correct, we will + // return net::OK. + if (!VerifyPartialResponse(info)) + error = net::ERR_INVALID_RESPONSE; + } else if (info.headers->response_code() != kHttpOK) { + // We didn't request a range but server didn't reply with "200 OK". + error = net::ERR_FAILED; + } } if (error != net::OK) { @@ -331,9 +305,9 @@ void BufferedResourceLoader::didReceiveResponse( partial_response_ = range_requested_; } - // Expected content length can be -1, in that case |content_length_| is + // |info.content_length| can be -1, in that case |content_length_| is // not specified and this is a streaming response. - content_length_ = response.expectedContentLength(); + content_length_ = info.content_length; // If we have not requested a range, then the size of the instance is equal // to the content length. @@ -344,12 +318,8 @@ void BufferedResourceLoader::didReceiveResponse( DoneStart(net::OK); } -void BufferedResourceLoader::didReceiveData( - WebURLLoader* loader, - const char* data, - int data_length) { - DCHECK(!completed_); - DCHECK_GT(data_length, 0); +void BufferedResourceLoader::OnReceivedData(const char* data, int len) { + DCHECK(bridge_.get()); // If this loader has been stopped, |buffer_| would be destroyed. // In this case we shouldn't do anything. @@ -357,7 +327,7 @@ void BufferedResourceLoader::didReceiveData( return; // Writes more data to |buffer_|. - buffer_->Append(reinterpret_cast<const uint8*>(data), data_length); + buffer_->Append(reinterpret_cast<const uint8*>(data), len); // If there is an active read request, try to fulfill the request. if (HasPendingRead() && CanFulfillRead()) { @@ -380,28 +350,18 @@ void BufferedResourceLoader::didReceiveData( NotifyNetworkEvent(); } -void BufferedResourceLoader::didDownloadData( - WebKit::WebURLLoader* loader, - int dataLength) { - NOTIMPLEMENTED(); -} - -void BufferedResourceLoader::didReceiveCachedMetadata( - WebURLLoader* loader, - const char* data, - int data_length) { - NOTIMPLEMENTED(); -} +void BufferedResourceLoader::OnCompletedRequest( + const URLRequestStatus& status, + const std::string& security_info, + const base::Time& completion_time) { + DCHECK(bridge_.get()); -void BufferedResourceLoader::didFinishLoading( - WebURLLoader* loader, - double finishTime) { - DCHECK(!completed_); + // Saves the information that the request has completed. completed_ = true; // If there is a start callback, calls it. if (start_callback_.get()) { - DoneStart(net::OK); + DoneStart(status.os_error()); } // If there is a pending read but the request has ended, returns with what @@ -410,11 +370,16 @@ void BufferedResourceLoader::didFinishLoading( // Make sure we have a valid buffer before we satisfy a read request. DCHECK(buffer_.get()); - // Try to fulfill with what is in the buffer. - if (CanFulfillRead()) - ReadInternal(); - else - DoneRead(net::ERR_CACHE_MISS); + if (status.is_success()) { + // Try to fulfill with what is in the buffer. + if (CanFulfillRead()) + ReadInternal(); + else + DoneRead(net::ERR_CACHE_MISS); + } else { + // If the request has failed, then fail the read. + DoneRead(net::ERR_FAILED); + } } // There must not be any outstanding read request. @@ -423,31 +388,10 @@ void BufferedResourceLoader::didFinishLoading( // Notify that network response is completed. NotifyNetworkEvent(); - url_loader_.reset(); - Release(); -} - -void BufferedResourceLoader::didFail( - WebURLLoader* loader, - const WebURLError& error) { - DCHECK(!completed_); - completed_ = true; - - // If there is a start callback, calls it. - if (start_callback_.get()) { - DoneStart(error.reason); - } - - // If there is a pending read but the request failed, return with the - // reason for the error. - if (HasPendingRead()) { - DoneRead(error.reason); - } - - // Notify that network response is completed. - NotifyNetworkEvent(); - - url_loader_.reset(); + // We incremented the reference count when the loader was started. We balance + // that reference here so that we get destroyed. This is also the only safe + // place to destroy the ResourceLoaderBridge. + bridge_.reset(); Release(); } @@ -461,8 +405,8 @@ void BufferedResourceLoader::EnableDeferIfNeeded() { buffer_->forward_bytes() >= buffer_->forward_capacity()) { deferred_ = true; - if (url_loader_.get()) - url_loader_->setDefersLoading(true); + if (bridge_.get()) + bridge_->SetDefersLoading(true); NotifyNetworkEvent(); } @@ -474,8 +418,8 @@ void BufferedResourceLoader::DisableDeferIfNeeded() { buffer_->forward_bytes() < buffer_->forward_capacity() / 2)) { deferred_ = false; - if (url_loader_.get()) - url_loader_->setDefersLoading(false); + if (bridge_.get()) + bridge_->SetDefersLoading(false); NotifyNetworkEvent(); } @@ -536,21 +480,18 @@ void BufferedResourceLoader::ReadInternal() { } bool BufferedResourceLoader::VerifyPartialResponse( - const WebURLResponse& response) { - int first_byte_position, last_byte_position, instance_size; - - if (!MultipartResponseDelegate::ReadContentRanges(response, - &first_byte_position, - &last_byte_position, - &instance_size)) { + const ResourceResponseInfo& info) { + int64 first_byte_position, last_byte_position, instance_size; + if (!info.headers->GetContentRange(&first_byte_position, + &last_byte_position, + &instance_size)) { return false; } - if (instance_size != kPositionNotSpecified) { + if (instance_size != kPositionNotSpecified) instance_size_ = instance_size; - } - if (first_byte_position_ != kPositionNotSpecified && + if (first_byte_position_ != -1 && first_byte_position_ != first_byte_position) { return false; } @@ -560,27 +501,6 @@ bool BufferedResourceLoader::VerifyPartialResponse( return true; } -std::string BufferedResourceLoader::GenerateHeaders( - int64 first_byte_position, - int64 last_byte_position) { - // Construct the value for the range header. - std::string header; - if (first_byte_position > kPositionNotSpecified && - last_byte_position > kPositionNotSpecified) { - if (first_byte_position <= last_byte_position) { - header = base::StringPrintf("bytes=%" PRId64 "-%" PRId64, - first_byte_position, - last_byte_position); - } - } else if (first_byte_position > kPositionNotSpecified) { - header = base::StringPrintf("bytes=%" PRId64 "-", - first_byte_position); - } else if (last_byte_position > kPositionNotSpecified) { - NOTIMPLEMENTED() << "Suffix range not implemented"; - } - return header; -} - void BufferedResourceLoader::DoneRead(int error) { read_callback_->RunWithParams(Tuple1<int>(error)); read_callback_.reset(); @@ -605,12 +525,12 @@ void BufferedResourceLoader::NotifyNetworkEvent() { // BufferedDataSource BufferedDataSource::BufferedDataSource( MessageLoop* render_loop, - WebFrame* frame) + webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) : total_bytes_(kPositionNotSpecified), loaded_(false), streaming_(false), - frame_(frame), single_origin_(true), + bridge_factory_(bridge_factory), loader_(NULL), network_activity_(false), initialize_callback_(NULL), @@ -638,7 +558,7 @@ BufferedResourceLoader* BufferedDataSource::CreateResourceLoader( int64 first_byte_position, int64 last_byte_position) { DCHECK(MessageLoop::current() == render_loop_); - return new BufferedResourceLoader(url_, + return new BufferedResourceLoader(bridge_factory_.get(), url_, first_byte_position, last_byte_position); } @@ -738,12 +658,12 @@ void BufferedDataSource::Abort() { // If we are told to abort, immediately return from any pending read // with an error. if (read_callback_.get()) { + { AutoLock auto_lock(lock_); DoneRead_Locked(net::ERR_FAILED); + } + CleanupTask(); } - - CleanupTask(); - frame_ = NULL; } ///////////////////////////////////////////////////////////////////////////// @@ -770,8 +690,7 @@ void BufferedDataSource::InitializeTask() { loader_ = CreateResourceLoader(0, 1024); loader_->Start( NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback), - frame_); + NewCallback(this, &BufferedDataSource::NetworkEventCallback)); } else { // For all other protocols, assume they support range request. We fetch // the full range of the resource to obtain the instance size because @@ -779,8 +698,7 @@ void BufferedDataSource::InitializeTask() { loader_ = CreateResourceLoader(-1, -1); loader_->Start( NewCallback(this, &BufferedDataSource::NonHttpInitialStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback), - frame_); + NewCallback(this, &BufferedDataSource::NetworkEventCallback)); } } @@ -857,8 +775,7 @@ void BufferedDataSource::RestartLoadingTask() { loader_->SetAllowDefer(!media_is_paused_); loader_->Start( NewCallback(this, &BufferedDataSource::PartialReadStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback), - frame_); + NewCallback(this, &BufferedDataSource::NetworkEventCallback)); } void BufferedDataSource::WatchDogTask() { @@ -889,8 +806,7 @@ void BufferedDataSource::WatchDogTask() { loader_->SetAllowDefer(!media_is_paused_); loader_->Start( NewCallback(this, &BufferedDataSource::PartialReadStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback), - frame_); + NewCallback(this, &BufferedDataSource::NetworkEventCallback)); } void BufferedDataSource::SetPlaybackRateTask(float playback_rate) { @@ -913,7 +829,7 @@ void BufferedDataSource::SetPlaybackRateTask(float playback_rate) { // prior to make this method call. void BufferedDataSource::ReadInternal() { DCHECK(MessageLoop::current() == render_loop_); - DCHECK(loader_); + DCHECK(loader_.get()); // First we prepare the intermediate read buffer for BufferedResourceLoader // to write to. @@ -988,8 +904,7 @@ void BufferedDataSource::HttpInitialStartCallback(int error) { loader_ = CreateResourceLoader(-1, -1); loader_->Start( NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback), - frame_); + NewCallback(this, &BufferedDataSource::NetworkEventCallback)); return; } |