Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: webkit/glue/media/simple_data_source.cc

Issue 8570010: Moving media-related files from webkit/glue/ to webkit/media/. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: minor fixes Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/glue/media/simple_data_source.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop.h"
9 #include "base/process_util.h"
10 #include "media/base/filter_host.h"
11 #include "media/base/media_log.h"
12 #include "net/base/data_url.h"
13 #include "net/base/load_flags.h"
14 #include "net/http/http_request_headers.h"
15 #include "net/url_request/url_request_status.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKitPlatformSupport .h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderOptions.h "
20 #include "webkit/glue/media/web_data_source_factory.h"
21 #include "webkit/glue/webkit_glue.h"
22
23 using WebKit::WebString;
24 using WebKit::WebURLLoaderOptions;
25
26 namespace webkit_glue {
27
28 static const char kDataScheme[] = "data";
29
30 static WebDataSource* NewSimpleDataSource(MessageLoop* render_loop,
31 WebKit::WebFrame* frame,
32 media::MediaLog* media_log) {
33 return new SimpleDataSource(render_loop, frame);
34 }
35
36 // static
37 media::DataSourceFactory* SimpleDataSource::CreateFactory(
38 MessageLoop* render_loop,
39 WebKit::WebFrame* frame,
40 media::MediaLog* media_log,
41 const WebDataSourceBuildObserverHack& build_observer) {
42 return new WebDataSourceFactory(render_loop, frame, media_log,
43 &NewSimpleDataSource, build_observer);
44 }
45
46 SimpleDataSource::SimpleDataSource(
47 MessageLoop* render_loop,
48 WebKit::WebFrame* frame)
49 : render_loop_(render_loop),
50 frame_(frame),
51 size_(-1),
52 single_origin_(true),
53 state_(UNINITIALIZED),
54 keep_test_loader_(false) {
55 DCHECK(render_loop);
56 }
57
58 SimpleDataSource::~SimpleDataSource() {
59 base::AutoLock auto_lock(lock_);
60 DCHECK(state_ == UNINITIALIZED || state_ == STOPPED);
61 }
62
63 void SimpleDataSource::set_host(media::FilterHost* host) {
64 DataSource::set_host(host);
65
66 base::AutoLock auto_lock(lock_);
67 if (state_ == INITIALIZED) {
68 UpdateHostState();
69 }
70 }
71
72 void SimpleDataSource::Stop(const base::Closure& callback) {
73 base::AutoLock auto_lock(lock_);
74 state_ = STOPPED;
75 if (!callback.is_null())
76 callback.Run();
77
78 // Post a task to the render thread to cancel loading the resource.
79 render_loop_->PostTask(FROM_HERE,
80 base::Bind(&SimpleDataSource::CancelTask, this));
81 }
82
83 void SimpleDataSource::Initialize(
84 const std::string& url,
85 const media::PipelineStatusCB& callback) {
86 // Reference to prevent destruction while inside the |initialize_cb_|
87 // call. This is a temporary fix to prevent crashes caused by holding the
88 // lock and running the destructor.
89 scoped_refptr<SimpleDataSource> destruction_guard(this);
90 {
91 base::AutoLock auto_lock(lock_);
92 DCHECK_EQ(state_, UNINITIALIZED);
93 DCHECK(!callback.is_null());
94 state_ = INITIALIZING;
95 initialize_cb_ = callback;
96
97 // Validate the URL.
98 url_ = GURL(url);
99 if (!url_.is_valid() || !IsProtocolSupportedForMedia(url_)) {
100 DoneInitialization_Locked(false);
101 return;
102 }
103
104 // Post a task to the render thread to start loading the resource.
105 render_loop_->PostTask(FROM_HERE,
106 base::Bind(&SimpleDataSource::StartTask, this));
107 }
108 }
109
110 void SimpleDataSource::CancelInitialize() {
111 base::AutoLock auto_lock(lock_);
112 DCHECK(!initialize_cb_.is_null());
113 state_ = STOPPED;
114 initialize_cb_.Reset();
115
116 // Post a task to the render thread to cancel loading the resource.
117 render_loop_->PostTask(FROM_HERE,
118 base::Bind(&SimpleDataSource::CancelTask, this));
119 }
120
121 void SimpleDataSource::Read(int64 position,
122 size_t size,
123 uint8* data,
124 const DataSource::ReadCallback& read_callback) {
125 DCHECK_GE(size_, 0);
126 if (position >= size_) {
127 read_callback.Run(0);
128 } else {
129 size_t copied = std::min(size, static_cast<size_t>(size_ - position));
130 memcpy(data, data_.c_str() + position, copied);
131 read_callback.Run(copied);
132 }
133 }
134
135 bool SimpleDataSource::GetSize(int64* size_out) {
136 *size_out = size_;
137 return true;
138 }
139
140 bool SimpleDataSource::IsStreaming() {
141 return false;
142 }
143
144 void SimpleDataSource::SetPreload(media::Preload preload) {
145 }
146
147 void SimpleDataSource::SetBitrate(int bitrate) {
148 }
149
150 void SimpleDataSource::SetURLLoaderForTest(WebKit::WebURLLoader* mock_loader) {
151 url_loader_.reset(mock_loader);
152 keep_test_loader_ = true;
153 }
154
155 void SimpleDataSource::willSendRequest(
156 WebKit::WebURLLoader* loader,
157 WebKit::WebURLRequest& newRequest,
158 const WebKit::WebURLResponse& redirectResponse) {
159 DCHECK(MessageLoop::current() == render_loop_);
160 base::AutoLock auto_lock(lock_);
161
162 // Only allow |single_origin_| if we haven't seen a different origin yet.
163 if (single_origin_)
164 single_origin_ = url_.GetOrigin() == GURL(newRequest.url()).GetOrigin();
165
166 url_ = newRequest.url();
167 }
168
169 void SimpleDataSource::didSendData(
170 WebKit::WebURLLoader* loader,
171 unsigned long long bytesSent,
172 unsigned long long totalBytesToBeSent) {
173 NOTIMPLEMENTED();
174 }
175
176 void SimpleDataSource::didReceiveResponse(
177 WebKit::WebURLLoader* loader,
178 const WebKit::WebURLResponse& response) {
179 DCHECK(MessageLoop::current() == render_loop_);
180 size_ = response.expectedContentLength();
181 }
182
183 void SimpleDataSource::didDownloadData(
184 WebKit::WebURLLoader* loader,
185 int dataLength) {
186 NOTIMPLEMENTED();
187 }
188
189 void SimpleDataSource::didReceiveData(
190 WebKit::WebURLLoader* loader,
191 const char* data,
192 int data_length,
193 int encoded_data_length) {
194 DCHECK(MessageLoop::current() == render_loop_);
195 data_.append(data, data_length);
196 }
197
198 void SimpleDataSource::didReceiveCachedMetadata(
199 WebKit::WebURLLoader* loader,
200 const char* data,
201 int dataLength) {
202 NOTIMPLEMENTED();
203 }
204
205 void SimpleDataSource::didFinishLoading(
206 WebKit::WebURLLoader* loader,
207 double finishTime) {
208 DCHECK(MessageLoop::current() == render_loop_);
209 // Reference to prevent destruction while inside the |initialize_cb_|
210 // call. This is a temporary fix to prevent crashes caused by holding the
211 // lock and running the destructor.
212 scoped_refptr<SimpleDataSource> destruction_guard(this);
213 {
214 base::AutoLock auto_lock(lock_);
215 // It's possible this gets called after Stop(), in which case |host_| is no
216 // longer valid.
217 if (state_ == STOPPED)
218 return;
219
220 // Otherwise we should be initializing and have created a WebURLLoader.
221 DCHECK_EQ(state_, INITIALIZING);
222
223 // If we don't get a content length or the request has failed, report it
224 // as a network error.
225 if (size_ == -1)
226 size_ = data_.length();
227 DCHECK(static_cast<size_t>(size_) == data_.length());
228
229 DoneInitialization_Locked(true);
230 }
231 }
232
233 void SimpleDataSource::didFail(
234 WebKit::WebURLLoader* loader,
235 const WebKit::WebURLError& error) {
236 DCHECK(MessageLoop::current() == render_loop_);
237 // Reference to prevent destruction while inside the |initialize_cb_|
238 // call. This is a temporary fix to prevent crashes caused by holding the
239 // lock and running the destructor.
240 scoped_refptr<SimpleDataSource> destruction_guard(this);
241 {
242 base::AutoLock auto_lock(lock_);
243 // It's possible this gets called after Stop(), in which case |host_| is no
244 // longer valid.
245 if (state_ == STOPPED)
246 return;
247
248 // Otherwise we should be initializing and have created a WebURLLoader.
249 DCHECK_EQ(state_, INITIALIZING);
250
251 // If we don't get a content length or the request has failed, report it
252 // as a network error.
253 if (size_ == -1)
254 size_ = data_.length();
255 DCHECK(static_cast<size_t>(size_) == data_.length());
256
257 DoneInitialization_Locked(false);
258 }
259 }
260
261 bool SimpleDataSource::HasSingleOrigin() {
262 DCHECK(MessageLoop::current() == render_loop_);
263 return single_origin_;
264 }
265
266 void SimpleDataSource::Abort() {
267 DCHECK(MessageLoop::current() == render_loop_);
268 frame_ = NULL;
269 }
270
271 void SimpleDataSource::StartTask() {
272 DCHECK(MessageLoop::current() == render_loop_);
273 // Reference to prevent destruction while inside the |initialize_cb_|
274 // call. This is a temporary fix to prevent crashes caused by holding the
275 // lock and running the destructor.
276 scoped_refptr<SimpleDataSource> destruction_guard(this);
277 {
278 base::AutoLock auto_lock(lock_);
279
280 // We may have stopped.
281 if (state_ == STOPPED)
282 return;
283
284 CHECK(frame_);
285
286 DCHECK_EQ(state_, INITIALIZING);
287
288 if (url_.SchemeIs(kDataScheme)) {
289 // If this using data protocol, we just need to decode it.
290 std::string mime_type, charset;
291 bool success = net::DataURL::Parse(url_, &mime_type, &charset, &data_);
292
293 // Don't care about the mime-type just proceed if decoding was successful.
294 size_ = data_.length();
295 DoneInitialization_Locked(success);
296 } else {
297 // Prepare the request.
298 WebKit::WebURLRequest request(url_);
299 request.setTargetType(WebKit::WebURLRequest::TargetIsMedia);
300
301 frame_->setReferrerForRequest(request, WebKit::WebURL());
302
303 // Disable compression, compression for audio/video doesn't make sense...
304 request.setHTTPHeaderField(
305 WebString::fromUTF8(net::HttpRequestHeaders::kAcceptEncoding),
306 WebString::fromUTF8("identity;q=1, *;q=0"));
307
308 // This flag is for unittests as we don't want to reset |url_loader|
309 if (!keep_test_loader_) {
310 WebURLLoaderOptions options;
311 options.allowCredentials = true;
312 options.crossOriginRequestPolicy =
313 WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
314 url_loader_.reset(frame_->createAssociatedURLLoader(options));
315 }
316
317 // Start the resource loading.
318 url_loader_->loadAsynchronously(request, this);
319 }
320 }
321 }
322
323 void SimpleDataSource::CancelTask() {
324 DCHECK(MessageLoop::current() == render_loop_);
325 base::AutoLock auto_lock(lock_);
326 DCHECK_EQ(state_, STOPPED);
327
328 // Cancel any pending requests.
329 if (url_loader_.get()) {
330 url_loader_->cancel();
331 url_loader_.reset();
332 }
333 }
334
335 void SimpleDataSource::DoneInitialization_Locked(bool success) {
336 lock_.AssertAcquired();
337 media::PipelineStatus status = media::PIPELINE_ERROR_NETWORK;
338 if (success) {
339 state_ = INITIALIZED;
340
341 UpdateHostState();
342 status = media::PIPELINE_OK;
343 } else {
344 state_ = UNINITIALIZED;
345 url_loader_.reset();
346 }
347
348 initialize_cb_.Run(status);
349 initialize_cb_.Reset();
350 }
351
352 void SimpleDataSource::UpdateHostState() {
353 if (host()) {
354 host()->SetTotalBytes(size_);
355 host()->SetBufferedBytes(size_);
356 // If scheme is file or data, say we are loaded.
357 host()->SetLoaded(url_.SchemeIsFile() || url_.SchemeIs(kDataScheme));
358 }
359 }
360
361 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « webkit/glue/media/simple_data_source.h ('k') | webkit/glue/media/simple_data_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698