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