Add long running gmail memory benchmark for background tab.
[chromium-blink-merge.git] / content / browser / presentation / presentation_service_impl_unittest.cc
blobef2106f308e9c90cf72d0ba58c60efb5be124a89
1 // Copyright 2015 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.
5 #include "base/location.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/run_loop.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/test/test_timeouts.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "content/browser/presentation/presentation_service_impl.h"
12 #include "content/public/browser/presentation_service_delegate.h"
13 #include "content/public/browser/presentation_session.h"
14 #include "content/public/common/presentation_constants.h"
15 #include "content/test/test_render_frame_host.h"
16 #include "content/test/test_render_view_host.h"
17 #include "content/test/test_web_contents.h"
18 #include "mojo/public/cpp/bindings/interface_ptr.h"
19 #include "testing/gmock/include/gmock/gmock.h"
21 using ::testing::_;
22 using ::testing::Eq;
23 using ::testing::InvokeWithoutArgs;
24 using ::testing::Mock;
25 using ::testing::Return;
26 using ::testing::SaveArg;
28 namespace content {
30 namespace {
32 // Matches mojo structs.
33 MATCHER_P(Equals, expected, "") {
34 return expected.Equals(arg);
37 const char kPresentationId[] = "presentationId";
38 const char kPresentationUrl[] = "http://foo.com/index.html";
40 bool ArePresentationSessionsEqual(
41 const presentation::PresentationSessionInfo& expected,
42 const presentation::PresentationSessionInfo& actual) {
43 return expected.url == actual.url && expected.id == actual.id;
46 bool ArePresentationSessionMessagesEqual(
47 const presentation::SessionMessage* expected,
48 const presentation::SessionMessage* actual) {
49 return expected->presentation_url == actual->presentation_url &&
50 expected->presentation_id == actual->presentation_id &&
51 expected->type == actual->type &&
52 expected->message == actual->message &&
53 expected->data.Equals(actual->data);
56 void DoNothing(
57 presentation::PresentationSessionInfoPtr info,
58 presentation::PresentationErrorPtr error) {
61 } // namespace
63 class MockPresentationServiceDelegate : public PresentationServiceDelegate {
64 public:
65 MOCK_METHOD3(AddObserver,
66 void(int render_process_id,
67 int render_frame_id,
68 PresentationServiceDelegate::Observer* observer));
69 MOCK_METHOD2(RemoveObserver,
70 void(int render_process_id, int render_frame_id));
71 MOCK_METHOD3(AddScreenAvailabilityListener,
72 bool(
73 int render_process_id,
74 int routing_id,
75 PresentationScreenAvailabilityListener* listener));
76 MOCK_METHOD3(RemoveScreenAvailabilityListener,
77 void(
78 int render_process_id,
79 int routing_id,
80 PresentationScreenAvailabilityListener* listener));
81 MOCK_METHOD2(Reset,
82 void(
83 int render_process_id,
84 int routing_id));
85 MOCK_METHOD3(SetDefaultPresentationUrl,
86 void(
87 int render_process_id,
88 int routing_id,
89 const std::string& default_presentation_url));
90 MOCK_METHOD5(StartSession,
91 void(
92 int render_process_id,
93 int render_frame_id,
94 const std::string& presentation_url,
95 const PresentationSessionSuccessCallback& success_cb,
96 const PresentationSessionErrorCallback& error_cb));
97 MOCK_METHOD6(JoinSession,
98 void(
99 int render_process_id,
100 int render_frame_id,
101 const std::string& presentation_url,
102 const std::string& presentation_id,
103 const PresentationSessionSuccessCallback& success_cb,
104 const PresentationSessionErrorCallback& error_cb));
105 MOCK_METHOD3(CloseSession,
106 void(int render_process_id,
107 int render_frame_id,
108 const std::string& presentation_id));
109 MOCK_METHOD3(ListenForSessionMessages,
110 void(
111 int render_process_id,
112 int render_frame_id,
113 const PresentationSessionMessageCallback& message_cb));
114 MOCK_METHOD4(SendMessageRawPtr,
115 void(
116 int render_process_id,
117 int render_frame_id,
118 PresentationSessionMessage* message_request,
119 const SendMessageCallback& send_message_cb));
120 void SendMessage(int render_process_id,
121 int render_frame_id,
122 scoped_ptr<PresentationSessionMessage> message_request,
123 const SendMessageCallback& send_message_cb) override {
124 SendMessageRawPtr(
125 render_process_id,
126 render_frame_id,
127 message_request.release(),
128 send_message_cb);
130 MOCK_METHOD3(
131 ListenForSessionStateChange,
132 void(int render_process_id,
133 int render_frame_id,
134 const content::SessionStateChangedCallback& state_changed_cb));
137 class MockPresentationServiceClient :
138 public presentation::PresentationServiceClient {
139 public:
140 MOCK_METHOD1(OnScreenAvailabilityUpdated, void(bool available));
141 void OnSessionStateChanged(
142 presentation::PresentationSessionInfoPtr session_info,
143 presentation::PresentationSessionState new_state) override {
144 OnSessionStateChanged(*session_info, new_state);
146 MOCK_METHOD2(OnSessionStateChanged,
147 void(const presentation::PresentationSessionInfo& session_info,
148 presentation::PresentationSessionState new_state));
149 void OnScreenAvailabilityNotSupported() override {
150 NOTIMPLEMENTED();
154 class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
155 public:
156 PresentationServiceImplTest() : default_session_started_count_(0) {}
158 void SetUp() override {
159 RenderViewHostImplTestHarness::SetUp();
161 auto request = mojo::GetProxy(&service_ptr_);
162 EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1);
163 service_impl_.reset(new PresentationServiceImpl(
164 contents()->GetMainFrame(), contents(), &mock_delegate_));
165 service_impl_->Bind(request.Pass());
167 presentation::PresentationServiceClientPtr client_ptr;
168 client_binding_.reset(
169 new mojo::Binding<presentation::PresentationServiceClient>(
170 &mock_client_, mojo::GetProxy(&client_ptr)));
171 service_impl_->SetClient(client_ptr.Pass());
174 void TearDown() override {
175 service_ptr_.reset();
176 if (service_impl_.get()) {
177 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
178 service_impl_.reset();
180 RenderViewHostImplTestHarness::TearDown();
183 void ListenForScreenAvailabilityAndWait(bool delegate_success) {
184 base::RunLoop run_loop;
185 // This will call to |service_impl_| via mojo. Process the message
186 // using RunLoop.
187 // The callback shouldn't be invoked since there is no availability
188 // result yet.
189 EXPECT_CALL(mock_delegate_, AddScreenAvailabilityListener(_, _, _))
190 .WillOnce(DoAll(
191 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
192 Return(delegate_success)));
193 service_ptr_->ListenForScreenAvailability();
194 run_loop.Run();
196 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
199 void RunLoopFor(base::TimeDelta duration) {
200 base::RunLoop run_loop;
201 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
202 FROM_HERE, run_loop.QuitClosure(), duration);
203 run_loop.Run();
206 void SaveQuitClosureAndRunLoop() {
207 base::RunLoop run_loop;
208 run_loop_quit_closure_ = run_loop.QuitClosure();
209 run_loop.Run();
210 run_loop_quit_closure_.Reset();
213 void SimulateScreenAvailabilityChangeAndWait(bool available) {
214 auto* listener = service_impl_->screen_availability_listener_.get();
215 ASSERT_TRUE(listener);
217 base::RunLoop run_loop;
218 EXPECT_CALL(mock_client_, OnScreenAvailabilityUpdated(available))
219 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
220 listener->OnScreenAvailabilityChanged(available);
221 run_loop.Run();
224 void ExpectReset() {
225 EXPECT_CALL(mock_delegate_, Reset(_, _)).Times(1);
228 void ExpectCleanState() {
229 EXPECT_TRUE(service_impl_->default_presentation_url_.empty());
230 EXPECT_FALSE(service_impl_->screen_availability_listener_.get());
231 EXPECT_FALSE(service_impl_->default_session_start_context_.get());
232 EXPECT_FALSE(service_impl_->on_session_messages_callback_.get());
235 void ExpectNewSessionMojoCallbackSuccess(
236 presentation::PresentationSessionInfoPtr info,
237 presentation::PresentationErrorPtr error) {
238 EXPECT_FALSE(info.is_null());
239 EXPECT_TRUE(error.is_null());
240 if (!run_loop_quit_closure_.is_null())
241 run_loop_quit_closure_.Run();
244 void ExpectNewSessionMojoCallbackError(
245 presentation::PresentationSessionInfoPtr info,
246 presentation::PresentationErrorPtr error) {
247 EXPECT_TRUE(info.is_null());
248 EXPECT_FALSE(error.is_null());
249 if (!run_loop_quit_closure_.is_null())
250 run_loop_quit_closure_.Run();
253 void ExpectDefaultSessionStarted(
254 const presentation::PresentationSessionInfo& expected_session,
255 presentation::PresentationSessionInfoPtr actual_session) {
256 ASSERT_TRUE(!actual_session.is_null());
257 EXPECT_TRUE(ArePresentationSessionsEqual(
258 expected_session, *actual_session));
259 ++default_session_started_count_;
260 if (!run_loop_quit_closure_.is_null())
261 run_loop_quit_closure_.Run();
264 void ExpectDefaultSessionNull(
265 presentation::PresentationSessionInfoPtr actual_session) {
266 EXPECT_TRUE(actual_session.is_null());
267 ++default_session_started_count_;
268 if (!run_loop_quit_closure_.is_null())
269 run_loop_quit_closure_.Run();
272 void ExpectSessionMessages(
273 mojo::Array<presentation::SessionMessagePtr> actual_msgs) {
274 EXPECT_TRUE(actual_msgs.size() == expected_msgs_.size());
275 for (size_t i = 0; i < actual_msgs.size(); ++i) {
276 EXPECT_TRUE(ArePresentationSessionMessagesEqual(expected_msgs_[i].get(),
277 actual_msgs[i].get()));
279 if (!run_loop_quit_closure_.is_null())
280 run_loop_quit_closure_.Run();
283 void ExpectSendMessageMojoCallback(bool success) {
284 EXPECT_TRUE(success);
285 EXPECT_FALSE(service_impl_->send_message_callback_);
286 if (!run_loop_quit_closure_.is_null())
287 run_loop_quit_closure_.Run();
290 void RunListenForSessionMessages(std::string& text_msg,
291 std::vector<uint8_t>& binary_data) {
294 expected_msgs_ = mojo::Array<presentation::SessionMessagePtr>::New(2);
295 expected_msgs_[0] = presentation::SessionMessage::New();
296 expected_msgs_[0]->presentation_url = kPresentationUrl;
297 expected_msgs_[0]->presentation_id = kPresentationId;
298 expected_msgs_[0]->type =
299 presentation::PresentationMessageType::PRESENTATION_MESSAGE_TYPE_TEXT;
300 expected_msgs_[0]->message = text_msg;
301 expected_msgs_[1] = presentation::SessionMessage::New();
302 expected_msgs_[1]->presentation_url = kPresentationUrl;
303 expected_msgs_[1]->presentation_id = kPresentationId;
304 expected_msgs_[1]->type = presentation::PresentationMessageType::
305 PRESENTATION_MESSAGE_TYPE_ARRAY_BUFFER;
306 expected_msgs_[1]->data = mojo::Array<uint8_t>::From(binary_data);
308 service_ptr_->ListenForSessionMessages(
309 base::Bind(&PresentationServiceImplTest::ExpectSessionMessages,
310 base::Unretained(this)));
312 base::RunLoop run_loop;
313 base::Callback<void(scoped_ptr<ScopedVector<PresentationSessionMessage>>)>
314 message_cb;
315 EXPECT_CALL(mock_delegate_, ListenForSessionMessages(_, _, _))
316 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
317 SaveArg<2>(&message_cb)));
318 run_loop.Run();
320 scoped_ptr<ScopedVector<PresentationSessionMessage>> messages(
321 new ScopedVector<PresentationSessionMessage>());
322 messages->push_back(
323 content::PresentationSessionMessage::CreateStringMessage(
324 kPresentationUrl, kPresentationId,
325 scoped_ptr<std::string>(new std::string(text_msg))));
326 messages->push_back(
327 content::PresentationSessionMessage::CreateArrayBufferMessage(
328 kPresentationUrl, kPresentationId,
329 scoped_ptr<std::vector<uint8_t>>(
330 new std::vector<uint8_t>(binary_data))));
331 message_cb.Run(messages.Pass());
332 SaveQuitClosureAndRunLoop();
335 MockPresentationServiceDelegate mock_delegate_;
337 scoped_ptr<PresentationServiceImpl> service_impl_;
338 mojo::InterfacePtr<presentation::PresentationService> service_ptr_;
340 MockPresentationServiceClient mock_client_;
341 scoped_ptr<mojo::Binding<presentation::PresentationServiceClient>>
342 client_binding_;
344 base::Closure run_loop_quit_closure_;
345 int default_session_started_count_;
346 mojo::Array<presentation::SessionMessagePtr> expected_msgs_;
349 TEST_F(PresentationServiceImplTest, ListenForScreenAvailability) {
350 ListenForScreenAvailabilityAndWait(true);
352 SimulateScreenAvailabilityChangeAndWait(true);
353 SimulateScreenAvailabilityChangeAndWait(false);
354 SimulateScreenAvailabilityChangeAndWait(true);
357 TEST_F(PresentationServiceImplTest, Reset) {
358 ListenForScreenAvailabilityAndWait(true);
360 ExpectReset();
361 service_impl_->Reset();
362 ExpectCleanState();
365 TEST_F(PresentationServiceImplTest, DidNavigateThisFrame) {
366 ListenForScreenAvailabilityAndWait(true);
368 ExpectReset();
369 service_impl_->DidNavigateAnyFrame(
370 contents()->GetMainFrame(),
371 content::LoadCommittedDetails(),
372 content::FrameNavigateParams());
373 ExpectCleanState();
376 TEST_F(PresentationServiceImplTest, DidNavigateOtherFrame) {
377 ListenForScreenAvailabilityAndWait(true);
379 // TODO(imcheng): How to get a different RenderFrameHost?
380 service_impl_->DidNavigateAnyFrame(
381 nullptr,
382 content::LoadCommittedDetails(),
383 content::FrameNavigateParams());
385 // Availability is reported and callback is invoked since it was not
386 // removed.
387 SimulateScreenAvailabilityChangeAndWait(true);
390 TEST_F(PresentationServiceImplTest, ThisRenderFrameDeleted) {
391 ListenForScreenAvailabilityAndWait(true);
393 ExpectReset();
395 // Since the frame matched the service, |service_impl_| will be deleted.
396 PresentationServiceImpl* service = service_impl_.release();
397 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
398 service->RenderFrameDeleted(contents()->GetMainFrame());
401 TEST_F(PresentationServiceImplTest, OtherRenderFrameDeleted) {
402 ListenForScreenAvailabilityAndWait(true);
404 // TODO(imcheng): How to get a different RenderFrameHost?
405 service_impl_->RenderFrameDeleted(nullptr);
407 // Availability is reported and callback should be invoked since listener
408 // has not been deleted.
409 SimulateScreenAvailabilityChangeAndWait(true);
412 TEST_F(PresentationServiceImplTest, DelegateFails) {
413 ListenForScreenAvailabilityAndWait(false);
414 ASSERT_FALSE(service_impl_->screen_availability_listener_.get());
417 TEST_F(PresentationServiceImplTest, SetDefaultPresentationUrl) {
418 std::string url1("http://fooUrl");
419 EXPECT_CALL(mock_delegate_,
420 SetDefaultPresentationUrl(_, _, Eq(url1)))
421 .Times(1);
422 service_impl_->SetDefaultPresentationURL(url1);
423 EXPECT_EQ(url1, service_impl_->default_presentation_url_);
425 // Now there should be a listener for DPU = |url1|.
426 ListenForScreenAvailabilityAndWait(true);
427 auto* listener = service_impl_->screen_availability_listener_.get();
428 ASSERT_TRUE(listener);
429 EXPECT_EQ(url1, listener->GetPresentationUrl());
431 std::string url2("http://barUrl");
432 // Sets different DPU.
433 // Adds listener for url2 and removes listener for url1.
434 EXPECT_CALL(
435 mock_delegate_,
436 AddScreenAvailabilityListener(_, _, _))
437 .WillOnce(Return(true));
438 EXPECT_CALL(
439 mock_delegate_,
440 RemoveScreenAvailabilityListener(_, _, _))
441 .Times(1);
442 EXPECT_CALL(mock_delegate_,
443 SetDefaultPresentationUrl(_, _, Eq(url2)))
444 .Times(1);
445 service_impl_->SetDefaultPresentationURL(url2);
446 EXPECT_EQ(url2, service_impl_->default_presentation_url_);
448 listener = service_impl_->screen_availability_listener_.get();
449 ASSERT_TRUE(listener);
450 EXPECT_EQ(url2, listener->GetPresentationUrl());
453 TEST_F(PresentationServiceImplTest, SetSameDefaultPresentationUrl) {
454 EXPECT_CALL(mock_delegate_,
455 SetDefaultPresentationUrl(_, _, Eq(kPresentationUrl)))
456 .Times(1);
457 service_impl_->SetDefaultPresentationURL(kPresentationUrl);
458 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
459 EXPECT_EQ(kPresentationUrl, service_impl_->default_presentation_url_);
461 // Same URL as before; no-ops.
462 service_impl_->SetDefaultPresentationURL(kPresentationUrl);
463 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
464 EXPECT_EQ(kPresentationUrl, service_impl_->default_presentation_url_);
467 TEST_F(PresentationServiceImplTest, StartSessionSuccess) {
468 service_ptr_->StartSession(
469 kPresentationUrl,
470 base::Bind(
471 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackSuccess,
472 base::Unretained(this)));
473 base::RunLoop run_loop;
474 base::Callback<void(const PresentationSessionInfo&)> success_cb;
475 EXPECT_CALL(mock_delegate_, StartSession(_, _, Eq(kPresentationUrl), _, _))
476 .WillOnce(DoAll(
477 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
478 SaveArg<3>(&success_cb)));
479 run_loop.Run();
480 success_cb.Run(PresentationSessionInfo(kPresentationUrl, kPresentationId));
481 SaveQuitClosureAndRunLoop();
484 TEST_F(PresentationServiceImplTest, StartSessionError) {
485 service_ptr_->StartSession(
486 kPresentationUrl,
487 base::Bind(
488 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackError,
489 base::Unretained(this)));
490 base::RunLoop run_loop;
491 base::Callback<void(const PresentationError&)> error_cb;
492 EXPECT_CALL(mock_delegate_, StartSession(_, _, Eq(kPresentationUrl), _, _))
493 .WillOnce(DoAll(
494 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
495 SaveArg<4>(&error_cb)));
496 run_loop.Run();
497 error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message"));
498 SaveQuitClosureAndRunLoop();
501 TEST_F(PresentationServiceImplTest, JoinSessionSuccess) {
502 service_ptr_->JoinSession(
503 kPresentationUrl,
504 kPresentationId,
505 base::Bind(
506 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackSuccess,
507 base::Unretained(this)));
508 base::RunLoop run_loop;
509 base::Callback<void(const PresentationSessionInfo&)> success_cb;
510 EXPECT_CALL(mock_delegate_, JoinSession(
511 _, _, Eq(kPresentationUrl), Eq(kPresentationId), _, _))
512 .WillOnce(DoAll(
513 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
514 SaveArg<4>(&success_cb)));
515 run_loop.Run();
516 success_cb.Run(PresentationSessionInfo(kPresentationUrl, kPresentationId));
517 SaveQuitClosureAndRunLoop();
520 TEST_F(PresentationServiceImplTest, JoinSessionError) {
521 service_ptr_->JoinSession(
522 kPresentationUrl,
523 kPresentationId,
524 base::Bind(
525 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackError,
526 base::Unretained(this)));
527 base::RunLoop run_loop;
528 base::Callback<void(const PresentationError&)> error_cb;
529 EXPECT_CALL(mock_delegate_, JoinSession(
530 _, _, Eq(kPresentationUrl), Eq(kPresentationId), _, _))
531 .WillOnce(DoAll(
532 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
533 SaveArg<5>(&error_cb)));
534 run_loop.Run();
535 error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message"));
536 SaveQuitClosureAndRunLoop();
539 TEST_F(PresentationServiceImplTest, CloseSession) {
540 service_ptr_->CloseSession(kPresentationUrl, kPresentationId);
541 base::RunLoop run_loop;
542 EXPECT_CALL(mock_delegate_, CloseSession(_, _, Eq(kPresentationId)))
543 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
544 run_loop.Run();
547 TEST_F(PresentationServiceImplTest, ListenForSessionMessages) {
548 std::string text_msg("123");
549 std::vector<uint8_t> binary_data(3, '\1');
550 RunListenForSessionMessages(text_msg, binary_data);
553 TEST_F(PresentationServiceImplTest, ListenForSessionMessagesWithEmptyMsg) {
554 std::string text_msg("");
555 std::vector<uint8_t> binary_data{};
556 RunListenForSessionMessages(text_msg, binary_data);
559 TEST_F(PresentationServiceImplTest, ReceiveSessionMessagesAfterReset) {
560 std::string text_msg("123");
561 expected_msgs_ = mojo::Array<presentation::SessionMessagePtr>();
562 service_ptr_->ListenForSessionMessages(
563 base::Bind(&PresentationServiceImplTest::ExpectSessionMessages,
564 base::Unretained(this)));
566 base::RunLoop run_loop;
567 base::Callback<void(scoped_ptr<ScopedVector<PresentationSessionMessage>>)>
568 message_cb;
569 EXPECT_CALL(mock_delegate_, ListenForSessionMessages(_, _, _))
570 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
571 SaveArg<2>(&message_cb)));
572 run_loop.Run();
574 scoped_ptr<ScopedVector<PresentationSessionMessage>> messages(
575 new ScopedVector<PresentationSessionMessage>());
576 messages->push_back(content::PresentationSessionMessage::CreateStringMessage(
577 kPresentationUrl, kPresentationId,
578 scoped_ptr<std::string>(new std::string(text_msg))));
579 ExpectReset();
580 service_impl_->Reset();
581 message_cb.Run(messages.Pass());
582 SaveQuitClosureAndRunLoop();
585 TEST_F(PresentationServiceImplTest, StartSessionInProgress) {
586 std::string presentation_url1("http://fooUrl");
587 std::string presentation_url2("http://barUrl");
588 service_ptr_->StartSession(presentation_url1,
589 base::Bind(&DoNothing));
590 // This request should fail immediately, since there is already a StartSession
591 // in progress.
592 service_ptr_->StartSession(
593 presentation_url2,
594 base::Bind(
595 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackError,
596 base::Unretained(this)));
597 SaveQuitClosureAndRunLoop();
600 TEST_F(PresentationServiceImplTest, ListenForDefaultSessionStart) {
601 presentation::PresentationSessionInfo expected_session;
602 expected_session.url = kPresentationUrl;
603 expected_session.id = kPresentationId;
604 service_ptr_->ListenForDefaultSessionStart(
605 base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionStarted,
606 base::Unretained(this),
607 expected_session));
608 RunLoopFor(base::TimeDelta::FromMilliseconds(50));
609 service_impl_->OnDefaultPresentationStarted(
610 content::PresentationSessionInfo(kPresentationUrl, kPresentationId));
611 SaveQuitClosureAndRunLoop();
612 EXPECT_EQ(1, default_session_started_count_);
615 TEST_F(PresentationServiceImplTest, ListenForDefaultSessionStartAfterSet) {
616 // Note that the callback will only pick up presentation_url2/id2 since
617 // ListenForDefaultSessionStart wasn't called yet when the DPU was still
618 // presentation_url1.
619 std::string presentation_url1("http://fooUrl1");
620 std::string presentation_id1("presentationId1");
621 std::string presentation_url2("http://fooUrl2");
622 std::string presentation_id2("presentationId2");
623 service_impl_->OnDefaultPresentationStarted(
624 content::PresentationSessionInfo(presentation_url1, presentation_id1));
626 presentation::PresentationSessionInfo expected_session;
627 expected_session.url = presentation_url2;
628 expected_session.id = presentation_id2;
629 service_ptr_->ListenForDefaultSessionStart(
630 base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionStarted,
631 base::Unretained(this),
632 expected_session));
633 RunLoopFor(base::TimeDelta::FromMilliseconds(50));
634 service_impl_->OnDefaultPresentationStarted(
635 content::PresentationSessionInfo(presentation_url2, presentation_id2));
636 SaveQuitClosureAndRunLoop();
637 EXPECT_EQ(1, default_session_started_count_);
640 TEST_F(PresentationServiceImplTest, DefaultSessionStartReset) {
641 service_ptr_->ListenForDefaultSessionStart(
642 base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionNull,
643 base::Unretained(this)));
644 RunLoopFor(TestTimeouts::tiny_timeout());
646 ExpectReset();
647 service_impl_->Reset();
648 ExpectCleanState();
649 SaveQuitClosureAndRunLoop();
650 EXPECT_EQ(1, default_session_started_count_);
653 TEST_F(PresentationServiceImplTest, SendStringMessage) {
654 std::string message("Test presentation session message");
656 presentation::SessionMessagePtr message_request(
657 presentation::SessionMessage::New());
658 message_request->presentation_url = kPresentationUrl;
659 message_request->presentation_id = kPresentationId;
660 message_request->type = presentation::PresentationMessageType::
661 PRESENTATION_MESSAGE_TYPE_TEXT;
662 message_request->message = message;
663 service_ptr_->SendSessionMessage(
664 message_request.Pass(),
665 base::Bind(
666 &PresentationServiceImplTest::ExpectSendMessageMojoCallback,
667 base::Unretained(this)));
669 base::RunLoop run_loop;
670 base::Callback<void(bool)> send_message_cb;
671 PresentationSessionMessage* test_message = nullptr;
672 EXPECT_CALL(mock_delegate_, SendMessageRawPtr(
673 _, _, _, _))
674 .WillOnce(DoAll(
675 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
676 SaveArg<2>(&test_message),
677 SaveArg<3>(&send_message_cb)));
678 run_loop.Run();
680 EXPECT_TRUE(test_message);
681 EXPECT_EQ(kPresentationUrl, test_message->presentation_url);
682 EXPECT_EQ(kPresentationId, test_message->presentation_id);
683 EXPECT_FALSE(test_message->is_binary());
684 EXPECT_TRUE(test_message->message.get()->size() <=
685 kMaxPresentationSessionMessageSize);
686 EXPECT_EQ(message, *(test_message->message.get()));
687 EXPECT_FALSE(test_message->data);
688 delete test_message;
689 send_message_cb.Run(true);
690 SaveQuitClosureAndRunLoop();
693 TEST_F(PresentationServiceImplTest, SendArrayBuffer) {
694 // Test Array buffer data.
695 const uint8 buffer[] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
696 std::vector<uint8> data;
697 data.assign(buffer, buffer + sizeof(buffer));
699 presentation::SessionMessagePtr message_request(
700 presentation::SessionMessage::New());
701 message_request->presentation_url = kPresentationUrl;
702 message_request->presentation_id = kPresentationId;
703 message_request->type = presentation::PresentationMessageType::
704 PRESENTATION_MESSAGE_TYPE_ARRAY_BUFFER;
705 message_request->data = mojo::Array<uint8>::From(data);
706 service_ptr_->SendSessionMessage(
707 message_request.Pass(),
708 base::Bind(
709 &PresentationServiceImplTest::ExpectSendMessageMojoCallback,
710 base::Unretained(this)));
712 base::RunLoop run_loop;
713 base::Callback<void(bool)> send_message_cb;
714 PresentationSessionMessage* test_message = nullptr;
715 EXPECT_CALL(mock_delegate_, SendMessageRawPtr(
716 _, _, _, _))
717 .WillOnce(DoAll(
718 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
719 SaveArg<2>(&test_message),
720 SaveArg<3>(&send_message_cb)));
721 run_loop.Run();
723 EXPECT_TRUE(test_message);
724 EXPECT_EQ(kPresentationUrl, test_message->presentation_url);
725 EXPECT_EQ(kPresentationId, test_message->presentation_id);
726 EXPECT_TRUE(test_message->is_binary());
727 EXPECT_EQ(PresentationMessageType::ARRAY_BUFFER, test_message->type);
728 EXPECT_FALSE(test_message->message);
729 EXPECT_EQ(data.size(), test_message->data.get()->size());
730 EXPECT_TRUE(test_message->data.get()->size() <=
731 kMaxPresentationSessionMessageSize);
732 EXPECT_EQ(0, memcmp(buffer, &(*test_message->data.get())[0], sizeof(buffer)));
733 delete test_message;
734 send_message_cb.Run(true);
735 SaveQuitClosureAndRunLoop();
738 TEST_F(PresentationServiceImplTest, SendArrayBufferWithExceedingLimit) {
739 // Create buffer with size exceeding the limit.
740 // Use same size as in content::kMaxPresentationSessionMessageSize.
741 const size_t kMaxBufferSizeInBytes = 64 * 1024; // 64 KB.
742 uint8 buffer[kMaxBufferSizeInBytes+1];
743 memset(buffer, 0, kMaxBufferSizeInBytes+1);
744 std::vector<uint8> data;
745 data.assign(buffer, buffer + sizeof(buffer));
747 presentation::SessionMessagePtr message_request(
748 presentation::SessionMessage::New());
749 message_request->presentation_url = kPresentationUrl;
750 message_request->presentation_id = kPresentationId;
751 message_request->type = presentation::PresentationMessageType::
752 PRESENTATION_MESSAGE_TYPE_ARRAY_BUFFER;
753 message_request->data = mojo::Array<uint8>::From(data);
754 service_ptr_->SendSessionMessage(
755 message_request.Pass(),
756 base::Bind(
757 &PresentationServiceImplTest::ExpectSendMessageMojoCallback,
758 base::Unretained(this)));
760 base::RunLoop run_loop;
761 base::Callback<void(bool)> send_message_cb;
762 PresentationSessionMessage* test_message = nullptr;
763 EXPECT_CALL(mock_delegate_, SendMessageRawPtr(
764 _, _, _, _))
765 .WillOnce(DoAll(
766 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
767 SaveArg<2>(&test_message),
768 SaveArg<3>(&send_message_cb)));
769 run_loop.Run();
771 EXPECT_FALSE(test_message);
772 send_message_cb.Run(true);
773 SaveQuitClosureAndRunLoop();
776 TEST_F(PresentationServiceImplTest, SendBlobData) {
777 const uint8 buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
778 std::vector<uint8> data;
779 data.assign(buffer, buffer + sizeof(buffer));
781 presentation::SessionMessagePtr message_request(
782 presentation::SessionMessage::New());
783 message_request->presentation_url = kPresentationUrl;
784 message_request->presentation_id = kPresentationId;
785 message_request->type =
786 presentation::PresentationMessageType::PRESENTATION_MESSAGE_TYPE_BLOB;
787 message_request->data = mojo::Array<uint8>::From(data);
788 service_ptr_->SendSessionMessage(
789 message_request.Pass(),
790 base::Bind(&PresentationServiceImplTest::ExpectSendMessageMojoCallback,
791 base::Unretained(this)));
793 base::RunLoop run_loop;
794 base::Callback<void(bool)> send_message_cb;
795 PresentationSessionMessage* test_message = nullptr;
796 EXPECT_CALL(mock_delegate_, SendMessageRawPtr(_, _, _, _))
797 .WillOnce(DoAll(
798 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
799 SaveArg<2>(&test_message),
800 SaveArg<3>(&send_message_cb)));
801 run_loop.Run();
803 EXPECT_TRUE(test_message);
804 EXPECT_EQ(kPresentationUrl, test_message->presentation_url);
805 EXPECT_EQ(kPresentationId, test_message->presentation_id);
806 EXPECT_TRUE(test_message->is_binary());
807 EXPECT_EQ(PresentationMessageType::BLOB, test_message->type);
808 EXPECT_FALSE(test_message->message);
809 EXPECT_EQ(data.size(), test_message->data.get()->size());
810 EXPECT_TRUE(test_message->data.get()->size() <=
811 kMaxPresentationSessionMessageSize);
812 EXPECT_EQ(0, memcmp(buffer, &(*test_message->data.get())[0], sizeof(buffer)));
813 delete test_message;
814 send_message_cb.Run(true);
815 SaveQuitClosureAndRunLoop();
818 TEST_F(PresentationServiceImplTest, MaxPendingJoinSessionRequests) {
819 const char* presentation_url = "http://fooUrl%d";
820 const char* presentation_id = "presentationId%d";
821 int num_requests = PresentationServiceImpl::kMaxNumQueuedSessionRequests;
822 int i = 0;
823 EXPECT_CALL(mock_delegate_, JoinSession(_, _, _, _, _, _))
824 .Times(num_requests);
825 for (; i < num_requests; ++i) {
826 service_ptr_->JoinSession(
827 base::StringPrintf(presentation_url, i),
828 base::StringPrintf(presentation_id, i),
829 base::Bind(&DoNothing));
832 // Exceeded maximum queue size, should invoke mojo callback with error.
833 service_ptr_->JoinSession(
834 base::StringPrintf(presentation_url, i),
835 base::StringPrintf(presentation_id, i),
836 base::Bind(
837 &PresentationServiceImplTest::ExpectNewSessionMojoCallbackError,
838 base::Unretained(this)));
839 SaveQuitClosureAndRunLoop();
842 TEST_F(PresentationServiceImplTest, ListenForSessionStateChange) {
843 base::RunLoop run_loop;
844 EXPECT_CALL(mock_delegate_, ListenForSessionStateChange(_, _, _))
845 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
846 service_ptr_->ListenForSessionStateChange();
847 run_loop.Run();
849 presentation::PresentationSessionInfo session_info;
850 session_info.url = kPresentationUrl;
851 session_info.id = kPresentationId;
853 EXPECT_CALL(mock_client_,
854 OnSessionStateChanged(
855 Equals(session_info),
856 presentation::PRESENTATION_SESSION_STATE_CONNECTED));
857 service_impl_->OnSessionStateChanged(
858 content::PresentationSessionInfo(kPresentationUrl, kPresentationId),
859 content::PRESENTATION_SESSION_STATE_CONNECTED);
862 } // namespace content