1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/glue/media/simple_data_source.h"
621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/process_util.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "media/base/filter_host.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/data_url.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/load_flags.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_status.h"
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebKitClient.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/glue/media/web_data_source_factory.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webkit_glue.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace webkit_glue {
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char kDataScheme[] = "data";
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic WebDataSource* NewSimpleDataSource(MessageLoop* render_loop,
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                          WebKit::WebFrame* frame) {
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return new SimpleDataSource(render_loop, frame);
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenmedia::DataSourceFactory* SimpleDataSource::CreateFactory(
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    MessageLoop* render_loop,
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WebKit::WebFrame* frame,
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WebDataSourceBuildObserverHack* build_observer) {
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return new WebDataSourceFactory(render_loop, frame, &NewSimpleDataSource,
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  build_observer);
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSimpleDataSource::SimpleDataSource(
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop* render_loop,
3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebFrame* frame)
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : render_loop_(render_loop),
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      frame_(frame),
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      size_(-1),
42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      single_origin_(true),
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      state_(UNINITIALIZED),
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      keep_test_loader_(false) {
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(render_loop);
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSimpleDataSource::~SimpleDataSource() {
4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock auto_lock(lock_);
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(state_ == UNINITIALIZED || state_ == STOPPED);
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SimpleDataSource::set_host(media::FilterHost* host) {
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DataSource::set_host(host);
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::AutoLock auto_lock(lock_);
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (state_ == INITIALIZED) {
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    UpdateHostState();
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SimpleDataSource::Stop(media::FilterCallback* callback) {
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock auto_lock(lock_);
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  state_ = STOPPED;
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (callback) {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback->Run();
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete callback;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Post a task to the render thread to cancel loading the resource.
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  render_loop_->PostTask(FROM_HERE,
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(this, &SimpleDataSource::CancelTask));
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SimpleDataSource::Initialize(
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string& url,
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    media::PipelineStatusCallback* callback) {
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Reference to prevent destruction while inside the |initialize_callback_|
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // call. This is a temporary fix to prevent crashes caused by holding the
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // lock and running the destructor.
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<SimpleDataSource> destruction_guard(this);
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::AutoLock auto_lock(lock_);
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK_EQ(state_, UNINITIALIZED);
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(callback);
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    state_ = INITIALIZING;
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    initialize_callback_.reset(callback);
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Validate the URL.
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SetURL(GURL(url));
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!url_.is_valid() || !IsProtocolSupportedForMedia(url_)) {
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DoneInitialization_Locked(false);
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Post a task to the render thread to start loading the resource.
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    render_loop_->PostTask(FROM_HERE,
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(this, &SimpleDataSource::StartTask));
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SimpleDataSource::CancelInitialize() {
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::AutoLock auto_lock(lock_);
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(initialize_callback_.get());
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state_ = STOPPED;
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  initialize_callback_.reset();
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Post a task to the render thread to cancel loading the resource.
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  render_loop_->PostTask(FROM_HERE,
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableMethod(this, &SimpleDataSource::CancelTask));
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst media::MediaFormat& SimpleDataSource::media_format() {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return media_format_;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SimpleDataSource::Read(int64 position,
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            size_t size,
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            uint8* data,
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            ReadCallback* read_callback) {
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_GE(size_, 0);
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (position >= size_) {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    read_callback->RunWithParams(Tuple1<size_t>(0));
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete read_callback;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    size_t copied = std::min(size, static_cast<size_t>(size_ - position));
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    memcpy(data, data_.c_str() + position, copied);
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    read_callback->RunWithParams(Tuple1<size_t>(copied));
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete read_callback;
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SimpleDataSource::GetSize(int64* size_out) {
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *size_out = size_;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SimpleDataSource::IsStreaming() {
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SimpleDataSource::SetPreload(media::Preload preload) {}
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SimpleDataSource::SetURLLoaderForTest(WebKit::WebURLLoader* mock_loader) {
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  url_loader_.reset(mock_loader);
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  keep_test_loader_ = true;
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SimpleDataSource::willSendRequest(
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebURLLoader* loader,
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebURLRequest& newRequest,
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const WebKit::WebURLResponse& redirectResponse) {
153513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(MessageLoop::current() == render_loop_);
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  base::AutoLock auto_lock(lock_);
15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Only allow |single_origin_| if we haven't seen a different origin yet.
15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (single_origin_)
15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    single_origin_ = url_.GetOrigin() == GURL(newRequest.url()).GetOrigin();
159513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
16021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  url_ = newRequest.url();
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SimpleDataSource::didSendData(
16421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebURLLoader* loader,
16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    unsigned long long bytesSent,
16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    unsigned long long totalBytesToBeSent) {
16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NOTIMPLEMENTED();
16821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
16921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SimpleDataSource::didReceiveResponse(
17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebURLLoader* loader,
17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const WebKit::WebURLResponse& response) {
173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(MessageLoop::current() == render_loop_);
17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  size_ = response.expectedContentLength();
17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SimpleDataSource::didDownloadData(
17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebURLLoader* loader,
17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    int dataLength) {
18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NOTIMPLEMENTED();
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SimpleDataSource::didReceiveData(
18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebURLLoader* loader,
18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const char* data,
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int data_length,
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int encoded_data_length) {
188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(MessageLoop::current() == render_loop_);
18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  data_.append(data, data_length);
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SimpleDataSource::didReceiveCachedMetadata(
19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebURLLoader* loader,
19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const char* data,
19521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    int dataLength) {
19621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NOTIMPLEMENTED();
19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SimpleDataSource::didFinishLoading(
20021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebURLLoader* loader,
20121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    double finishTime) {
202513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(MessageLoop::current() == render_loop_);
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Reference to prevent destruction while inside the |initialize_callback_|
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // call. This is a temporary fix to prevent crashes caused by holding the
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // lock and running the destructor.
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<SimpleDataSource> destruction_guard(this);
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::AutoLock auto_lock(lock_);
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // It's possible this gets called after Stop(), in which case |host_| is no
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // longer valid.
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (state_ == STOPPED)
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Otherwise we should be initializing and have created a WebURLLoader.
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK_EQ(state_, INITIALIZING);
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If we don't get a content length or the request has failed, report it
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // as a network error.
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (size_ == -1)
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      size_ = data_.length();
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(static_cast<size_t>(size_) == data_.length());
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DoneInitialization_Locked(true);
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
22521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
22621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SimpleDataSource::didFail(
22821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebKit::WebURLLoader* loader,
22921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const WebKit::WebURLError& error) {
23021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(MessageLoop::current() == render_loop_);
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Reference to prevent destruction while inside the |initialize_callback_|
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // call. This is a temporary fix to prevent crashes caused by holding the
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // lock and running the destructor.
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<SimpleDataSource> destruction_guard(this);
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::AutoLock auto_lock(lock_);
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // It's possible this gets called after Stop(), in which case |host_| is no
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // longer valid.
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (state_ == STOPPED)
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Otherwise we should be initializing and have created a WebURLLoader.
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK_EQ(state_, INITIALIZING);
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If we don't get a content length or the request has failed, report it
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // as a network error.
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (size_ == -1)
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      size_ = data_.length();
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(static_cast<size_t>(size_) == data_.length());
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DoneInitialization_Locked(false);
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
255513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool SimpleDataSource::HasSingleOrigin() {
256513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(MessageLoop::current() == render_loop_);
257513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return single_origin_;
258513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
259513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
260513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid SimpleDataSource::Abort() {
261513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(MessageLoop::current() == render_loop_);
26221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  frame_ = NULL;
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SimpleDataSource::SetURL(const GURL& url) {
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_ = url;
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  media_format_.Clear();
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  media_format_.SetAsString(media::MediaFormat::kURL, url.spec());
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SimpleDataSource::StartTask() {
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(MessageLoop::current() == render_loop_);
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Reference to prevent destruction while inside the |initialize_callback_|
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // call. This is a temporary fix to prevent crashes caused by holding the
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // lock and running the destructor.
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<SimpleDataSource> destruction_guard(this);
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::AutoLock auto_lock(lock_);
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // We may have stopped.
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (state_ == STOPPED)
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    CHECK(frame_);
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK_EQ(state_, INITIALIZING);
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (url_.SchemeIs(kDataScheme)) {
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // If this using data protocol, we just need to decode it.
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::string mime_type, charset;
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      bool success = net::DataURL::Parse(url_, &mime_type, &charset, &data_);
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Don't care about the mime-type just proceed if decoding was successful.
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      size_ = data_.length();
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DoneInitialization_Locked(success);
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Prepare the request.
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      WebKit::WebURLRequest request(url_);
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      request.setTargetType(WebKit::WebURLRequest::TargetIsMedia);
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      frame_->setReferrerForRequest(request, WebKit::WebURL());
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // This flag is for unittests as we don't want to reset |url_loader|
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!keep_test_loader_)
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        url_loader_.reset(frame_->createAssociatedURLLoader());
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Start the resource loading.
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url_loader_->loadAsynchronously(request, this);
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SimpleDataSource::CancelTask() {
314513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(MessageLoop::current() == render_loop_);
31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::AutoLock auto_lock(lock_);
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(state_, STOPPED);
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cancel any pending requests.
31921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (url_loader_.get()) {
32021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    url_loader_->cancel();
32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    url_loader_.reset();
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SimpleDataSource::DoneInitialization_Locked(bool success) {
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  lock_.AssertAcquired();
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  media::PipelineStatus status = media::PIPELINE_ERROR_NETWORK;
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (success) {
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    state_ = INITIALIZED;
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    UpdateHostState();
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    status = media::PIPELINE_OK;
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    state_ = UNINITIALIZED;
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    url_loader_.reset();
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<media::PipelineStatusCallback> initialize_callback(
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      initialize_callback_.release());
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  initialize_callback->Run(status);
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SimpleDataSource::UpdateHostState() {
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (host()) {
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    host()->SetTotalBytes(size_);
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    host()->SetBufferedBytes(size_);
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If scheme is file or data, say we are loaded.
34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    host()->SetLoaded(url_.SchemeIsFile() || url_.SchemeIs(kDataScheme));
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace webkit_glue
353