OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/test/test_timeouts.h" | 8 #include "base/test/test_timeouts.h" |
9 #include "media/base/media_log.h" | 9 #include "media/base/media_log.h" |
10 #include "media/base/mock_callback.h" | 10 #include "media/base/mock_callback.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 using webkit_glue::MockWebFrameClient; | 43 using webkit_glue::MockWebFrameClient; |
44 using webkit_glue::MockWebURLLoader; | 44 using webkit_glue::MockWebURLLoader; |
45 | 45 |
46 namespace webkit_media { | 46 namespace webkit_media { |
47 | 47 |
48 static const char* kHttpUrl = "http://test"; | 48 static const char* kHttpUrl = "http://test"; |
49 static const char* kFileUrl = "file://test"; | 49 static const char* kFileUrl = "file://test"; |
50 static const int kDataSize = 1024; | 50 static const int kDataSize = 1024; |
51 static const int kMaxCacheMissesBeforeFailTest = 20; | 51 static const int kMaxCacheMissesBeforeFailTest = 20; |
52 | 52 |
53 enum NetworkState { | 53 enum SourceType { |
54 NONE, | 54 NONE, |
55 LOADED, | 55 LOCAL, |
56 LOADING | 56 REMOTE |
57 }; | 57 }; |
58 | 58 |
59 // A mock BufferedDataSource to inject mock BufferedResourceLoader through | 59 // A mock BufferedDataSource to inject mock BufferedResourceLoader through |
60 // CreateResourceLoader() method. | 60 // CreateResourceLoader() method. |
61 class MockBufferedDataSource : public BufferedDataSource { | 61 class MockBufferedDataSource : public BufferedDataSource { |
62 public: | 62 public: |
63 MockBufferedDataSource(MessageLoop* message_loop, WebFrame* frame) | 63 MockBufferedDataSource(MessageLoop* message_loop, WebFrame* frame) |
64 : BufferedDataSource(message_loop, frame, new media::MediaLog()) { | 64 : BufferedDataSource(message_loop, frame, new media::MediaLog()) { |
65 } | 65 } |
66 | 66 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 | 126 |
127 EXPECT_CALL(*loader_, Start(NotNull(), _, NotNull())) | 127 EXPECT_CALL(*loader_, Start(NotNull(), _, NotNull())) |
128 .WillOnce( | 128 .WillOnce( |
129 DoAll(Assign(&error_, start_error), | 129 DoAll(Assign(&error_, start_error), |
130 Invoke(this, | 130 Invoke(this, |
131 &BufferedDataSourceTest::InvokeStartCallback))); | 131 &BufferedDataSourceTest::InvokeStartCallback))); |
132 } | 132 } |
133 | 133 |
134 void InitializeDataSource(const char* url, int error, | 134 void InitializeDataSource(const char* url, int error, |
135 bool partial_response, int64 instance_size, | 135 bool partial_response, int64 instance_size, |
136 NetworkState networkState) { | 136 SourceType source_type) { |
137 // Saves the url first. | 137 // Saves the url first. |
138 gurl_ = GURL(url); | 138 gurl_ = GURL(url); |
139 | 139 |
140 data_source_ = new MockBufferedDataSource(MessageLoop::current(), | 140 data_source_ = new MockBufferedDataSource(MessageLoop::current(), |
141 view_->mainFrame()); | 141 view_->mainFrame()); |
142 data_source_->set_host(&host_); | 142 data_source_->set_host(&host_); |
143 | 143 |
144 scoped_refptr<NiceMock<MockBufferedResourceLoader> > first_loader( | 144 scoped_refptr<NiceMock<MockBufferedResourceLoader> > first_loader( |
145 new NiceMock<MockBufferedResourceLoader>()); | 145 new NiceMock<MockBufferedResourceLoader>()); |
146 | 146 |
147 // Creates the mock loader to be injected. | 147 // Creates the mock loader to be injected. |
148 loader_ = first_loader; | 148 loader_ = first_loader; |
149 | 149 |
150 bool initialized_ok = (error == net::OK); | 150 bool initialized_ok = (error == net::OK); |
151 bool loaded = networkState == LOADED; | 151 bool local_source = source_type == LOCAL; |
152 { | 152 { |
153 InSequence s; | 153 InSequence s; |
154 ExpectCreateAndStartResourceLoader(error); | 154 ExpectCreateAndStartResourceLoader(error); |
155 | 155 |
156 // In the case of an invalid partial response we expect a second loader | 156 // In the case of an invalid partial response we expect a second loader |
157 // to be created. | 157 // to be created. |
158 if (partial_response && (error == net::ERR_INVALID_RESPONSE)) { | 158 if (partial_response && (error == net::ERR_INVALID_RESPONSE)) { |
159 // Verify that the initial loader is stopped. | 159 // Verify that the initial loader is stopped. |
160 EXPECT_CALL(*loader_, url()) | 160 EXPECT_CALL(*loader_, url()) |
161 .WillRepeatedly(ReturnRef(gurl_)); | 161 .WillRepeatedly(ReturnRef(gurl_)); |
(...skipping 20 matching lines...) Expand all Loading... |
182 .WillByDefault(Return(instance_size)); | 182 .WillByDefault(Return(instance_size)); |
183 | 183 |
184 // range_supported() return true if we expect to get a partial response. | 184 // range_supported() return true if we expect to get a partial response. |
185 ON_CALL(*loader_, range_supported()) | 185 ON_CALL(*loader_, range_supported()) |
186 .WillByDefault(Return(partial_response)); | 186 .WillByDefault(Return(partial_response)); |
187 | 187 |
188 ON_CALL(*loader_, url()) | 188 ON_CALL(*loader_, url()) |
189 .WillByDefault(ReturnRef(gurl_)); | 189 .WillByDefault(ReturnRef(gurl_)); |
190 media::PipelineStatus expected_init_status = media::PIPELINE_OK; | 190 media::PipelineStatus expected_init_status = media::PIPELINE_OK; |
191 if (initialized_ok) { | 191 if (initialized_ok) { |
192 // Expected loaded or not. | 192 // Media is a local file or not. |
193 EXPECT_CALL(host_, SetLoaded(loaded)); | 193 EXPECT_CALL(host_, SetLocalSourceFromFilter(local_source)); |
194 | 194 |
195 if (instance_size != -1) | 195 if (instance_size != -1) |
196 EXPECT_CALL(host_, SetTotalBytes(instance_size)); | 196 EXPECT_CALL(host_, SetTotalBytes(instance_size)); |
197 | 197 |
198 if (loaded) | 198 if (local_source) |
199 EXPECT_CALL(host_, SetBufferedBytes(instance_size)); | 199 EXPECT_CALL(host_, SetBufferedBytes(instance_size)); |
200 else | 200 else |
201 EXPECT_CALL(host_, SetBufferedBytes(0)); | 201 EXPECT_CALL(host_, SetBufferedBytes(0)); |
202 | 202 |
203 if (!partial_response || instance_size == -1) | 203 if (!partial_response || instance_size == -1) |
204 EXPECT_CALL(host_, SetStreaming(true)); | 204 EXPECT_CALL(host_, SetStreaming(true)); |
205 | 205 |
206 } else { | 206 } else { |
207 expected_init_status = media::PIPELINE_ERROR_NETWORK; | 207 expected_init_status = media::PIPELINE_ERROR_NETWORK; |
208 EXPECT_CALL(*loader_, Stop()); | 208 EXPECT_CALL(*loader_, Stop()); |
209 } | 209 } |
210 | 210 |
211 // Actual initialization of the data source. | 211 // Actual initialization of the data source. |
212 data_source_->Initialize(url, | 212 data_source_->Initialize(url, |
213 media::NewExpectedStatusCB(expected_init_status)); | 213 media::NewExpectedStatusCB(expected_init_status)); |
214 message_loop_->RunAllPending(); | 214 message_loop_->RunAllPending(); |
215 | 215 |
216 if (initialized_ok) { | 216 if (initialized_ok) { |
217 // Verify the size of the data source. | 217 // Verify the size of the data source. |
218 int64 size; | 218 int64 size; |
219 if (instance_size != -1 && (loaded || partial_response)) { | 219 if (instance_size != -1 && (local_source || partial_response)) { |
220 EXPECT_TRUE(data_source_->GetSize(&size)); | 220 EXPECT_TRUE(data_source_->GetSize(&size)); |
221 EXPECT_EQ(instance_size, size); | 221 EXPECT_EQ(instance_size, size); |
222 } else { | 222 } else { |
223 EXPECT_TRUE(data_source_->IsStreaming()); | 223 EXPECT_TRUE(data_source_->IsStreaming()); |
224 } | 224 } |
225 } | 225 } |
226 } | 226 } |
227 | 227 |
228 void StopDataSource() { | 228 void StopDataSource() { |
229 if (loader_) { | 229 if (loader_) { |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 uint8 buffer_[1024]; | 445 uint8 buffer_[1024]; |
446 uint8 data_[1024]; | 446 uint8 data_[1024]; |
447 | 447 |
448 int cache_miss_count_; | 448 int cache_miss_count_; |
449 | 449 |
450 private: | 450 private: |
451 DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceTest); | 451 DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceTest); |
452 }; | 452 }; |
453 | 453 |
454 TEST_F(BufferedDataSourceTest, InitializationSuccess) { | 454 TEST_F(BufferedDataSourceTest, InitializationSuccess) { |
455 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING); | 455 InitializeDataSource(kHttpUrl, net::OK, true, 1024, REMOTE); |
456 StopDataSource(); | 456 StopDataSource(); |
457 } | 457 } |
458 | 458 |
459 TEST_F(BufferedDataSourceTest, InitiailizationFailed) { | 459 TEST_F(BufferedDataSourceTest, InitiailizationFailed) { |
460 InitializeDataSource(kHttpUrl, net::ERR_FILE_NOT_FOUND, false, 0, NONE); | 460 InitializeDataSource(kHttpUrl, net::ERR_FILE_NOT_FOUND, false, 0, NONE); |
461 StopDataSource(); | 461 StopDataSource(); |
462 } | 462 } |
463 | 463 |
464 TEST_F(BufferedDataSourceTest, MissingContentLength) { | 464 TEST_F(BufferedDataSourceTest, MissingContentLength) { |
465 InitializeDataSource(kHttpUrl, net::OK, true, -1, LOADING); | 465 InitializeDataSource(kHttpUrl, net::OK, true, -1, REMOTE); |
466 StopDataSource(); | 466 StopDataSource(); |
467 } | 467 } |
468 | 468 |
469 TEST_F(BufferedDataSourceTest, RangeRequestNotSupported) { | 469 TEST_F(BufferedDataSourceTest, RangeRequestNotSupported) { |
470 InitializeDataSource(kHttpUrl, net::OK, false, 1024, LOADING); | 470 InitializeDataSource(kHttpUrl, net::OK, false, 1024, REMOTE); |
471 StopDataSource(); | 471 StopDataSource(); |
472 } | 472 } |
473 | 473 |
474 // Test the case where we get a 206 response, but no Content-Range header. | 474 // Test the case where we get a 206 response, but no Content-Range header. |
475 TEST_F(BufferedDataSourceTest, MissingContentRange) { | 475 TEST_F(BufferedDataSourceTest, MissingContentRange) { |
476 InitializeDataSource(kHttpUrl, net::ERR_INVALID_RESPONSE, true, 1024, | 476 InitializeDataSource(kHttpUrl, net::ERR_INVALID_RESPONSE, true, 1024, |
477 LOADING); | 477 REMOTE); |
478 StopDataSource(); | 478 StopDataSource(); |
479 } | 479 } |
480 | 480 |
481 TEST_F(BufferedDataSourceTest, | 481 TEST_F(BufferedDataSourceTest, |
482 MissingContentLengthAndRangeRequestNotSupported) { | 482 MissingContentLengthAndRangeRequestNotSupported) { |
483 InitializeDataSource(kHttpUrl, net::OK, false, -1, LOADING); | 483 InitializeDataSource(kHttpUrl, net::OK, false, -1, REMOTE); |
484 StopDataSource(); | 484 StopDataSource(); |
485 } | 485 } |
486 | 486 |
487 TEST_F(BufferedDataSourceTest, ReadCacheHit) { | 487 TEST_F(BufferedDataSourceTest, ReadCacheHit) { |
488 InitializeDataSource(kHttpUrl, net::OK, true, 25, LOADING); | 488 InitializeDataSource(kHttpUrl, net::OK, true, 25, REMOTE); |
489 | 489 |
490 // Performs read with cache hit. | 490 // Performs read with cache hit. |
491 ReadDataSourceHit(10, 10, 10); | 491 ReadDataSourceHit(10, 10, 10); |
492 | 492 |
493 // Performs read with cache hit but partially filled. | 493 // Performs read with cache hit but partially filled. |
494 ReadDataSourceHit(20, 10, 5); | 494 ReadDataSourceHit(20, 10, 5); |
495 | 495 |
496 StopDataSource(); | 496 StopDataSource(); |
497 } | 497 } |
498 | 498 |
499 TEST_F(BufferedDataSourceTest, ReadCacheMiss) { | 499 TEST_F(BufferedDataSourceTest, ReadCacheMiss) { |
500 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING); | 500 InitializeDataSource(kHttpUrl, net::OK, true, 1024, REMOTE); |
501 ReadDataSourceMiss(1000, 10, net::OK); | 501 ReadDataSourceMiss(1000, 10, net::OK); |
502 ReadDataSourceMiss(20, 10, net::OK); | 502 ReadDataSourceMiss(20, 10, net::OK); |
503 StopDataSource(); | 503 StopDataSource(); |
504 } | 504 } |
505 | 505 |
506 // Test the case where the initial response from the server indicates that | 506 // Test the case where the initial response from the server indicates that |
507 // Range requests are supported, but a later request prove otherwise. | 507 // Range requests are supported, but a later request prove otherwise. |
508 TEST_F(BufferedDataSourceTest, ServerLiesAboutRangeSupport) { | 508 TEST_F(BufferedDataSourceTest, ServerLiesAboutRangeSupport) { |
509 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING); | 509 InitializeDataSource(kHttpUrl, net::OK, true, 1024, REMOTE); |
510 ReadDataSourceHit(10, 10, 10); | 510 ReadDataSourceHit(10, 10, 10); |
511 ReadDataSourceMiss(1000, 10, net::ERR_INVALID_RESPONSE); | 511 ReadDataSourceMiss(1000, 10, net::ERR_INVALID_RESPONSE); |
512 StopDataSource(); | 512 StopDataSource(); |
513 } | 513 } |
514 | 514 |
515 TEST_F(BufferedDataSourceTest, ReadHang) { | 515 TEST_F(BufferedDataSourceTest, ReadHang) { |
516 InitializeDataSource(kHttpUrl, net::OK, true, 25, LOADING); | 516 InitializeDataSource(kHttpUrl, net::OK, true, 25, REMOTE); |
517 ReadDataSourceHang(10, 10); | 517 ReadDataSourceHang(10, 10); |
518 StopDataSource(); | 518 StopDataSource(); |
519 } | 519 } |
520 | 520 |
521 TEST_F(BufferedDataSourceTest, ReadFailed) { | 521 TEST_F(BufferedDataSourceTest, ReadFailed) { |
522 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING); | 522 InitializeDataSource(kHttpUrl, net::OK, true, 1024, REMOTE); |
523 ReadDataSourceHit(10, 10, 10); | 523 ReadDataSourceHit(10, 10, 10); |
524 ReadDataSourceFailed(10, 10, net::ERR_CONNECTION_RESET); | 524 ReadDataSourceFailed(10, 10, net::ERR_CONNECTION_RESET); |
525 StopDataSource(); | 525 StopDataSource(); |
526 } | 526 } |
527 | 527 |
528 // Helper that sets |*value| to true. Useful for binding into a Closure. | 528 // Helper that sets |*value| to true. Useful for binding into a Closure. |
529 static void SetTrue(bool* value) { | 529 static void SetTrue(bool* value) { |
530 *value = true; | 530 *value = true; |
531 } | 531 } |
532 | 532 |
533 // This test makes sure that Stop() does not require a task to run on | 533 // This test makes sure that Stop() does not require a task to run on |
534 // |message_loop_| before it calls its callback. This prevents accidental | 534 // |message_loop_| before it calls its callback. This prevents accidental |
535 // introduction of a pipeline teardown deadlock. The pipeline owner blocks | 535 // introduction of a pipeline teardown deadlock. The pipeline owner blocks |
536 // the render message loop while waiting for Stop() to complete. Since this | 536 // the render message loop while waiting for Stop() to complete. Since this |
537 // object runs on the render message loop, Stop() will not complete if it | 537 // object runs on the render message loop, Stop() will not complete if it |
538 // requires a task to run on the the message loop that is being blocked. | 538 // requires a task to run on the the message loop that is being blocked. |
539 TEST_F(BufferedDataSourceTest, StopDoesNotUseMessageLoopForCallback) { | 539 TEST_F(BufferedDataSourceTest, StopDoesNotUseMessageLoopForCallback) { |
540 InitializeDataSource(kFileUrl, net::OK, true, 1024, LOADED); | 540 InitializeDataSource(kFileUrl, net::OK, true, 1024, LOCAL); |
541 | 541 |
542 // Stop() the data source, using a callback that lets us verify that it was | 542 // Stop() the data source, using a callback that lets us verify that it was |
543 // called before Stop() returns. This is to make sure that the callback does | 543 // called before Stop() returns. This is to make sure that the callback does |
544 // not require |message_loop_| to execute tasks before being called. | 544 // not require |message_loop_| to execute tasks before being called. |
545 bool stop_done_called = false; | 545 bool stop_done_called = false; |
546 data_source_->Stop(base::Bind(&SetTrue, &stop_done_called)); | 546 data_source_->Stop(base::Bind(&SetTrue, &stop_done_called)); |
547 | 547 |
548 // Verify that the callback was called inside the Stop() call. | 548 // Verify that the callback was called inside the Stop() call. |
549 EXPECT_TRUE(stop_done_called); | 549 EXPECT_TRUE(stop_done_called); |
550 | 550 |
551 message_loop_->RunAllPending(); | 551 message_loop_->RunAllPending(); |
552 } | 552 } |
553 | 553 |
554 TEST_F(BufferedDataSourceTest, AbortDuringPendingRead) { | 554 TEST_F(BufferedDataSourceTest, AbortDuringPendingRead) { |
555 InitializeDataSource(kFileUrl, net::OK, true, 1024, LOADED); | 555 InitializeDataSource(kFileUrl, net::OK, true, 1024, LOCAL); |
556 | 556 |
557 // Setup a way to verify that Read() is not called on the loader. | 557 // Setup a way to verify that Read() is not called on the loader. |
558 // We are doing this to make sure that the ReadTask() is still on | 558 // We are doing this to make sure that the ReadTask() is still on |
559 // the message loop queue when Abort() is called. | 559 // the message loop queue when Abort() is called. |
560 bool read_called = false; | 560 bool read_called = false; |
561 ON_CALL(*loader_, Read(_, _, _ , _)) | 561 ON_CALL(*loader_, Read(_, _, _ , _)) |
562 .WillByDefault(DoAll(Assign(&read_called, true), | 562 .WillByDefault(DoAll(Assign(&read_called, true), |
563 DeleteArg<3>())); | 563 DeleteArg<3>())); |
564 | 564 |
565 // Initiate a Read() on the data source, but don't allow the | 565 // Initiate a Read() on the data source, but don't allow the |
(...skipping 21 matching lines...) Expand all Loading... |
587 // Allow cleanup task to run. | 587 // Allow cleanup task to run. |
588 message_loop_->RunAllPending(); | 588 message_loop_->RunAllPending(); |
589 | 589 |
590 // Verify that Read() was not called on the loader. | 590 // Verify that Read() was not called on the loader. |
591 EXPECT_FALSE(read_called); | 591 EXPECT_FALSE(read_called); |
592 } | 592 } |
593 | 593 |
594 // Test that we only allow a limited number of cache misses for a | 594 // Test that we only allow a limited number of cache misses for a |
595 // single Read() request. | 595 // single Read() request. |
596 TEST_F(BufferedDataSourceTest, BoundedCacheMisses) { | 596 TEST_F(BufferedDataSourceTest, BoundedCacheMisses) { |
597 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING); | 597 InitializeDataSource(kHttpUrl, net::OK, true, 1024, REMOTE); |
598 | 598 |
599 ReadDataSourceAlwaysCacheMiss(0, 10); | 599 ReadDataSourceAlwaysCacheMiss(0, 10); |
600 | 600 |
601 StopDataSource(); | 601 StopDataSource(); |
602 } | 602 } |
603 | 603 |
604 // TODO(scherkus): de-dupe from buffered_resource_loader_unittest.cc | 604 // TODO(scherkus): de-dupe from buffered_resource_loader_unittest.cc |
605 ACTION_P(RequestCanceled, loader) { | 605 ACTION_P(RequestCanceled, loader) { |
606 WebURLError error; | 606 WebURLError error; |
607 error.reason = net::ERR_ABORTED; | 607 error.reason = net::ERR_ABORTED; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 response.setHTTPHeaderField(WebString::fromUTF8("Accept-Ranges"), | 676 response.setHTTPHeaderField(WebString::fromUTF8("Accept-Ranges"), |
677 WebString::fromUTF8("bytes")); | 677 WebString::fromUTF8("bytes")); |
678 response.setHTTPHeaderField(WebString::fromUTF8("Content-Range"), | 678 response.setHTTPHeaderField(WebString::fromUTF8("Content-Range"), |
679 WebString::fromUTF8("bytes 0-4999999/5000000")); | 679 WebString::fromUTF8("bytes 0-4999999/5000000")); |
680 response.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), | 680 response.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), |
681 WebString::fromUTF8("5000000")); | 681 WebString::fromUTF8("5000000")); |
682 response.setExpectedContentLength(5000000); | 682 response.setExpectedContentLength(5000000); |
683 response.setHTTPStatusCode(206); | 683 response.setHTTPStatusCode(206); |
684 | 684 |
685 // We should receive corresponding information about the media resource. | 685 // We should receive corresponding information about the media resource. |
686 EXPECT_CALL(host_, SetLoaded(false)); | 686 EXPECT_CALL(host_, SetLocalSourceFromFilter(false)); |
687 EXPECT_CALL(host_, SetTotalBytes(5000000)); | 687 EXPECT_CALL(host_, SetTotalBytes(5000000)); |
688 EXPECT_CALL(host_, SetBufferedBytes(0)); | 688 EXPECT_CALL(host_, SetBufferedBytes(0)); |
689 | 689 |
690 data_source_->loader()->didReceiveResponse(data_source_->url_loader(), | 690 data_source_->loader()->didReceiveResponse(data_source_->url_loader(), |
691 response); | 691 response); |
692 | 692 |
693 message_loop_->RunAllPending(); | 693 message_loop_->RunAllPending(); |
694 } | 694 } |
695 | 695 |
696 void StopDataSource() { | 696 void StopDataSource() { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 message_loop_->RunAllPending(); | 783 message_loop_->RunAllPending(); |
784 | 784 |
785 // Verify loader changed but still has same bitrate. | 785 // Verify loader changed but still has same bitrate. |
786 EXPECT_NE(old_loader, data_source_->loader().get()); | 786 EXPECT_NE(old_loader, data_source_->loader().get()); |
787 EXPECT_EQ(2.0f, loader_playback_rate()); | 787 EXPECT_EQ(2.0f, loader_playback_rate()); |
788 | 788 |
789 StopDataSource(); | 789 StopDataSource(); |
790 } | 790 } |
791 | 791 |
792 } // namespace webkit_media | 792 } // namespace webkit_media |
OLD | NEW |