OLD | NEW |
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/message_loop.h" | 5 #include "base/message_loop.h" |
6 #include "base/process_util.h" | 6 #include "base/process_util.h" |
7 #include "media/base/filter_host.h" | 7 #include "media/base/filter_host.h" |
8 #include "net/base/load_flags.h" | 8 #include "net/base/load_flags.h" |
9 #include "net/base/data_url.h" | 9 #include "net/base/data_url.h" |
10 #include "net/http/http_response_headers.h" | |
11 #include "net/url_request/url_request_status.h" | 10 #include "net/url_request/url_request_status.h" |
| 11 #include "third_party/WebKit/WebKit/chromium/public/WebKit.h" |
| 12 #include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h" |
12 #include "webkit/glue/media/simple_data_source.h" | 13 #include "webkit/glue/media/simple_data_source.h" |
13 #include "webkit/glue/resource_loader_bridge.h" | |
14 #include "webkit/glue/webkit_glue.h" | 14 #include "webkit/glue/webkit_glue.h" |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 const char kHttpScheme[] = "http"; | 18 const char kHttpScheme[] = "http"; |
19 const char kHttpsScheme[] = "https"; | 19 const char kHttpsScheme[] = "https"; |
20 const char kDataScheme[] = "data"; | 20 const char kDataScheme[] = "data"; |
21 | 21 |
22 // A helper method that accepts only HTTP, HTTPS and FILE protocol. | 22 // A helper method that accepts only HTTP, HTTPS and FILE protocol. |
23 bool IsDataProtocol(const GURL& url) { | 23 bool IsDataProtocol(const GURL& url) { |
24 return url.SchemeIs(kDataScheme); | 24 return url.SchemeIs(kDataScheme); |
25 } | 25 } |
26 | 26 |
27 } // namespace | 27 } // namespace |
28 | 28 |
29 namespace webkit_glue { | 29 namespace webkit_glue { |
30 | 30 |
31 SimpleDataSource::SimpleDataSource( | 31 SimpleDataSource::SimpleDataSource( |
32 MessageLoop* render_loop, | 32 MessageLoop* render_loop, |
33 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) | 33 WebKit::WebFrame* frame) |
34 : render_loop_(render_loop), | 34 : render_loop_(render_loop), |
35 bridge_factory_(bridge_factory), | 35 frame_(frame), |
36 size_(-1), | 36 size_(-1), |
37 single_origin_(true), | 37 single_origin_(true), |
38 state_(UNINITIALIZED) { | 38 state_(UNINITIALIZED), |
| 39 keep_test_loader_(false) { |
39 DCHECK(render_loop); | 40 DCHECK(render_loop); |
40 } | 41 } |
41 | 42 |
42 SimpleDataSource::~SimpleDataSource() { | 43 SimpleDataSource::~SimpleDataSource() { |
43 AutoLock auto_lock(lock_); | 44 AutoLock auto_lock(lock_); |
44 DCHECK(state_ == UNINITIALIZED || state_ == STOPPED); | 45 DCHECK(state_ == UNINITIALIZED || state_ == STOPPED); |
45 } | 46 } |
46 | 47 |
47 void SimpleDataSource::Stop(media::FilterCallback* callback) { | 48 void SimpleDataSource::Stop(media::FilterCallback* callback) { |
48 AutoLock auto_lock(lock_); | 49 AutoLock auto_lock(lock_); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 102 |
102 bool SimpleDataSource::GetSize(int64* size_out) { | 103 bool SimpleDataSource::GetSize(int64* size_out) { |
103 *size_out = size_; | 104 *size_out = size_; |
104 return true; | 105 return true; |
105 } | 106 } |
106 | 107 |
107 bool SimpleDataSource::IsStreaming() { | 108 bool SimpleDataSource::IsStreaming() { |
108 return false; | 109 return false; |
109 } | 110 } |
110 | 111 |
111 bool SimpleDataSource::OnReceivedRedirect( | 112 void SimpleDataSource::SetURLLoaderForTest(WebKit::WebURLLoader* mock_loader) { |
112 const GURL& new_url, | 113 url_loader_.reset(mock_loader); |
113 const webkit_glue::ResourceResponseInfo& info, | 114 keep_test_loader_ = true; |
114 bool* has_new_first_party_for_cookies, | |
115 GURL* new_first_party_for_cookies) { | |
116 DCHECK(MessageLoop::current() == render_loop_); | |
117 single_origin_ = url_.GetOrigin() == new_url.GetOrigin(); | |
118 | |
119 // TODO(wtc): should we return a new first party for cookies URL? | |
120 *has_new_first_party_for_cookies = false; | |
121 return true; | |
122 } | 115 } |
123 | 116 |
124 void SimpleDataSource::OnReceivedResponse( | 117 void SimpleDataSource::willSendRequest( |
125 const webkit_glue::ResourceResponseInfo& info, | 118 WebKit::WebURLLoader* loader, |
126 bool content_filtered) { | 119 WebKit::WebURLRequest& newRequest, |
| 120 const WebKit::WebURLResponse& redirectResponse) { |
127 DCHECK(MessageLoop::current() == render_loop_); | 121 DCHECK(MessageLoop::current() == render_loop_); |
128 size_ = info.content_length; | 122 single_origin_ = url_.GetOrigin() == GURL(newRequest.url()).GetOrigin(); |
| 123 |
| 124 url_ = newRequest.url(); |
129 } | 125 } |
130 | 126 |
131 void SimpleDataSource::OnReceivedData(const char* data, int len) { | 127 void SimpleDataSource::didSendData( |
132 DCHECK(MessageLoop::current() == render_loop_); | 128 WebKit::WebURLLoader* loader, |
133 data_.append(data, len); | 129 unsigned long long bytesSent, |
| 130 unsigned long long totalBytesToBeSent) { |
| 131 NOTIMPLEMENTED(); |
134 } | 132 } |
135 | 133 |
136 void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, | 134 void SimpleDataSource::didReceiveResponse( |
137 const std::string& security_info, | 135 WebKit::WebURLLoader* loader, |
138 const base::Time& completion_time) { | 136 const WebKit::WebURLResponse& response) { |
| 137 DCHECK(MessageLoop::current() == render_loop_); |
| 138 size_ = response.expectedContentLength(); |
| 139 } |
| 140 |
| 141 void SimpleDataSource::didDownloadData( |
| 142 WebKit::WebURLLoader* loader, |
| 143 int dataLength) { |
| 144 NOTIMPLEMENTED(); |
| 145 } |
| 146 |
| 147 void SimpleDataSource::didReceiveData( |
| 148 WebKit::WebURLLoader* loader, |
| 149 const char* data, |
| 150 int data_length) { |
| 151 DCHECK(MessageLoop::current() == render_loop_); |
| 152 data_.append(data, data_length); |
| 153 } |
| 154 |
| 155 void SimpleDataSource::didReceiveCachedMetadata( |
| 156 WebKit::WebURLLoader* loader, |
| 157 const char* data, |
| 158 int dataLength) { |
| 159 NOTIMPLEMENTED(); |
| 160 } |
| 161 |
| 162 void SimpleDataSource::didFinishLoading( |
| 163 WebKit::WebURLLoader* loader, |
| 164 double finishTime) { |
139 DCHECK(MessageLoop::current() == render_loop_); | 165 DCHECK(MessageLoop::current() == render_loop_); |
140 AutoLock auto_lock(lock_); | 166 AutoLock auto_lock(lock_); |
141 // It's possible this gets called after Stop(), in which case |host_| is no | 167 // It's possible this gets called after Stop(), in which case |host_| is no |
| 168 // longer valid. |
| 169 if (state_ == STOPPED) |
| 170 return; |
| 171 |
| 172 // Otherwise we should be initializing and have created a WebURLLoader. |
| 173 DCHECK_EQ(state_, INITIALIZING); |
| 174 |
| 175 // If we don't get a content length or the request has failed, report it |
| 176 // as a network error. |
| 177 if (size_ == -1) |
| 178 size_ = data_.length(); |
| 179 DCHECK(static_cast<size_t>(size_) == data_.length()); |
| 180 |
| 181 DoneInitialization_Locked(true); |
| 182 } |
| 183 |
| 184 void SimpleDataSource::didFail( |
| 185 WebKit::WebURLLoader* loader, |
| 186 const WebKit::WebURLError& error) { |
| 187 DCHECK(MessageLoop::current() == render_loop_); |
| 188 AutoLock auto_lock(lock_); |
| 189 // It's possible this gets called after Stop(), in which case |host_| is no |
142 // longer valid. | 190 // longer valid. |
143 if (state_ == STOPPED) | 191 if (state_ == STOPPED) |
144 return; | 192 return; |
145 | 193 |
146 // Otherwise we should be initializing and have created a bridge. | 194 // Otherwise we should be initializing and have created a WebURLLoader. |
147 DCHECK_EQ(state_, INITIALIZING); | 195 DCHECK_EQ(state_, INITIALIZING); |
148 DCHECK(bridge_.get()); | |
149 bridge_.reset(); | |
150 | 196 |
151 // If we don't get a content length or the request has failed, report it | 197 // If we don't get a content length or the request has failed, report it |
152 // as a network error. | 198 // as a network error. |
153 if (size_ == -1) | 199 if (size_ == -1) |
154 size_ = data_.length(); | 200 size_ = data_.length(); |
155 DCHECK(static_cast<size_t>(size_) == data_.length()); | 201 DCHECK(static_cast<size_t>(size_) == data_.length()); |
156 | 202 |
157 DoneInitialization_Locked(status.is_success()); | 203 DoneInitialization_Locked(false); |
158 } | 204 } |
159 | 205 |
160 bool SimpleDataSource::HasSingleOrigin() { | 206 bool SimpleDataSource::HasSingleOrigin() { |
161 DCHECK(MessageLoop::current() == render_loop_); | 207 DCHECK(MessageLoop::current() == render_loop_); |
162 return single_origin_; | 208 return single_origin_; |
163 } | 209 } |
164 | 210 |
165 void SimpleDataSource::Abort() { | 211 void SimpleDataSource::Abort() { |
166 DCHECK(MessageLoop::current() == render_loop_); | 212 DCHECK(MessageLoop::current() == render_loop_); |
167 NOTIMPLEMENTED(); | 213 frame_ = NULL; |
168 } | 214 } |
169 | 215 |
170 void SimpleDataSource::SetURL(const GURL& url) { | 216 void SimpleDataSource::SetURL(const GURL& url) { |
171 url_ = url; | 217 url_ = url; |
172 media_format_.Clear(); | 218 media_format_.Clear(); |
173 media_format_.SetAsString(media::MediaFormat::kMimeType, | 219 media_format_.SetAsString(media::MediaFormat::kMimeType, |
174 media::mime_type::kApplicationOctetStream); | 220 media::mime_type::kApplicationOctetStream); |
175 media_format_.SetAsString(media::MediaFormat::kURL, url.spec()); | 221 media_format_.SetAsString(media::MediaFormat::kURL, url.spec()); |
176 } | 222 } |
177 | 223 |
178 void SimpleDataSource::StartTask() { | 224 void SimpleDataSource::StartTask() { |
179 DCHECK(MessageLoop::current() == render_loop_); | 225 DCHECK(MessageLoop::current() == render_loop_); |
180 AutoLock auto_lock(lock_); | 226 AutoLock auto_lock(lock_); |
181 | 227 |
182 // We may have stopped. | 228 // We may have stopped. |
183 if (state_ == STOPPED) | 229 if (state_ == STOPPED) |
184 return; | 230 return; |
185 | 231 |
| 232 CHECK(frame_); |
| 233 |
186 DCHECK_EQ(state_, INITIALIZING); | 234 DCHECK_EQ(state_, INITIALIZING); |
187 | 235 |
188 if (IsDataProtocol(url_)) { | 236 if (IsDataProtocol(url_)) { |
189 // If this using data protocol, we just need to decode it. | 237 // If this using data protocol, we just need to decode it. |
190 std::string mime_type, charset; | 238 std::string mime_type, charset; |
191 bool success = net::DataURL::Parse(url_, &mime_type, &charset, &data_); | 239 bool success = net::DataURL::Parse(url_, &mime_type, &charset, &data_); |
192 | 240 |
193 // Don't care about the mime-type just proceed if decoding was successful. | 241 // Don't care about the mime-type just proceed if decoding was successful. |
194 size_ = data_.length(); | 242 size_ = data_.length(); |
195 DoneInitialization_Locked(success); | 243 DoneInitialization_Locked(success); |
196 } else { | 244 } else { |
197 // Create our bridge and start loading the resource. | 245 // Prepare the request. |
198 bridge_.reset(bridge_factory_->CreateBridge( | 246 WebKit::WebURLRequest request(url_); |
199 url_, net::LOAD_BYPASS_CACHE, -1, -1)); | 247 |
200 bridge_->Start(this); | 248 frame_->setReferrerForRequest(request, WebKit::WebURL()); |
| 249 // TODO(annacc): we should be using createAssociatedURLLoader() instead? |
| 250 frame_->dispatchWillSendRequest(request); |
| 251 |
| 252 // This flag is for unittests as we don't want to reset |url_loader| |
| 253 if (!keep_test_loader_) |
| 254 url_loader_.reset(WebKit::webKitClient()->createURLLoader()); |
| 255 |
| 256 // Start the resource loading. |
| 257 url_loader_->loadAsynchronously(request, this); |
201 } | 258 } |
202 } | 259 } |
203 | 260 |
204 void SimpleDataSource::CancelTask() { | 261 void SimpleDataSource::CancelTask() { |
205 DCHECK(MessageLoop::current() == render_loop_); | 262 DCHECK(MessageLoop::current() == render_loop_); |
206 AutoLock auto_lock(lock_); | 263 AutoLock auto_lock(lock_); |
207 DCHECK_EQ(state_, STOPPED); | 264 DCHECK_EQ(state_, STOPPED); |
208 | 265 |
209 // Cancel any pending requests. | 266 // Cancel any pending requests. |
210 if (bridge_.get()) { | 267 if (url_loader_.get()) { |
211 bridge_->Cancel(); | 268 url_loader_->cancel(); |
212 bridge_.reset(); | 269 url_loader_.reset(); |
213 } | 270 } |
214 } | 271 } |
215 | 272 |
216 void SimpleDataSource::DoneInitialization_Locked(bool success) { | 273 void SimpleDataSource::DoneInitialization_Locked(bool success) { |
217 lock_.AssertAcquired(); | 274 lock_.AssertAcquired(); |
218 if (success) { | 275 if (success) { |
219 state_ = INITIALIZED; | 276 state_ = INITIALIZED; |
220 host()->SetTotalBytes(size_); | 277 host()->SetTotalBytes(size_); |
221 host()->SetBufferedBytes(size_); | 278 host()->SetBufferedBytes(size_); |
222 // If scheme is file or data, say we are loaded. | 279 // If scheme is file or data, say we are loaded. |
223 host()->SetLoaded(url_.SchemeIsFile() || IsDataProtocol(url_)); | 280 host()->SetLoaded(url_.SchemeIsFile() || IsDataProtocol(url_)); |
224 } else { | 281 } else { |
225 host()->SetError(media::PIPELINE_ERROR_NETWORK); | 282 host()->SetError(media::PIPELINE_ERROR_NETWORK); |
226 } | 283 } |
227 initialize_callback_->Run(); | 284 initialize_callback_->Run(); |
228 initialize_callback_.reset(); | 285 initialize_callback_.reset(); |
229 } | 286 } |
230 | 287 |
231 } // namespace webkit_glue | 288 } // namespace webkit_glue |
OLD | NEW |