// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/process_util.h" #include "chrome/renderer/media/simple_data_source.h" #include "chrome/renderer/render_thread.h" #include "chrome/renderer/render_view.h" #include "media/base/filter_host.h" #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_request_status.h" #include "webkit/glue/webappcachecontext.h" SimpleDataSource::SimpleDataSource(int32 routing_id) : routing_id_(routing_id), render_loop_(RenderThread::current()->message_loop()), size_(0), position_(0) { } SimpleDataSource::~SimpleDataSource() {} void SimpleDataSource::Stop() {} bool SimpleDataSource::Initialize(const std::string& url) { SetURL(url); // Validate the URL. GURL gurl(url); if (!gurl.is_valid()) { return false; } // Create our bridge and post a task to start loading the resource. bridge_.reset(RenderThread::current()->resource_dispatcher()->CreateBridge( "GET", gurl, gurl, GURL::EmptyGURL(), // TODO(scherkus): provide referer here. "null", // TODO(abarth): provide frame_origin "null", // TODO(abarth): provide main_frame_origin "", net::LOAD_BYPASS_CACHE, base::GetCurrentProcId(), ResourceType::MEDIA, 0, // TODO(michaeln): delegate->mediaplayer->frame-> // app_cache_context()->context_id() // For now don't service media resource requests from the appcache. WebAppCacheContext::kNoAppCacheContextId, routing_id_)); render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &SimpleDataSource::StartTask)); return true; } const media::MediaFormat& SimpleDataSource::media_format() { return media_format_; } size_t SimpleDataSource::Read(uint8* data, size_t size) { size_t copied = std::min(size, static_cast<size_t>(size_ - position_)); memcpy(data, data_.c_str() + position_, copied); position_ += copied; return copied; } bool SimpleDataSource::GetPosition(int64* position_out) { *position_out = position_; return true; } bool SimpleDataSource::SetPosition(int64 position) { if (position < 0 || position > size_) return false; position_ = position; return true; } bool SimpleDataSource::GetSize(int64* size_out) { *size_out = size_; return true; } bool SimpleDataSource::IsSeekable() { return true; } void SimpleDataSource::OnDownloadProgress(uint64 position, uint64 size) {} void SimpleDataSource::OnUploadProgress(uint64 position, uint64 size) {} void SimpleDataSource::OnReceivedRedirect(const GURL& new_url) { SetURL(new_url.spec()); } void SimpleDataSource::OnReceivedResponse( const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, bool content_filtered) { // This is a simple data source, so we assume 200 responses with the content // length provided. DCHECK(info.headers->response_code() == 200); DCHECK(info.content_length != -1); size_ = info.content_length; } void SimpleDataSource::OnReceivedData(const char* data, int len) { data_.append(data, len); } void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, const std::string& security_info) { DCHECK(size_ == data_.length()); position_ = 0; bridge_.reset(); host_->InitializationComplete(); } std::string SimpleDataSource::GetURLForDebugging() { return url_; } void SimpleDataSource::SetURL(const std::string& url) { url_ = url; media_format_.Clear(); media_format_.SetAsString(media::MediaFormat::kMimeType, media::mime_type::kApplicationOctetStream); media_format_.SetAsString(media::MediaFormat::kURL, url); } void SimpleDataSource::StartTask() { DCHECK(MessageLoop::current() == render_loop_); bridge_->Start(this); }