blob: f60bc3f1400e105fecd224405d864b391b41edfe [file] [log] [blame]
imcheng9f515d02015-02-10 20:09:241// 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.
4
dcheng36b6aec92015-12-26 06:16:365#include "content/browser/presentation/presentation_service_impl.h"
6
avib7348942015-12-25 20:57:107#include <stddef.h>
8#include <stdint.h>
dcheng59716272016-04-09 05:19:089
mfoltz0dc2a6b2017-03-07 18:24:1910#include <iterator>
dcheng59716272016-04-09 05:19:0811#include <memory>
kmarshallf5367c642015-08-20 19:23:1312#include <string>
dcheng36b6aec92015-12-26 06:16:3613#include <utility>
kmarshallf5367c642015-08-20 19:23:1314#include <vector>
15
Sebastien Marchandf8cbfab2019-01-25 16:02:3016#include "base/bind.h"
danakjdb9ae7942020-11-11 16:01:3517#include "base/callback_helpers.h"
Mario Sanchez Prada2311a9e2019-08-26 14:29:4918#include "base/macros.h"
Mario Sanchez Prada2ae29e5a2019-08-26 14:42:2319#include "base/optional.h"
imcheng9f515d02015-02-10 20:09:2420#include "base/run_loop.h"
Lei Zhange02299a2021-04-26 23:12:2421#include "base/strings/stringprintf.h"
Rakina Zata Amnic7bc8262019-12-09 05:21:2222#include "content/browser/presentation/presentation_test_utils.h"
Derek Cheng1071a232017-07-25 22:23:5623#include "content/public/browser/presentation_request.h"
imcheng9f515d02015-02-10 20:09:2424#include "content/public/browser/presentation_service_delegate.h"
Camille Lamyfa5767c2019-01-07 14:53:5925#include "content/public/test/mock_navigation_handle.h"
imcheng9f515d02015-02-10 20:09:2426#include "content/test/test_render_frame_host.h"
27#include "content/test/test_render_view_host.h"
28#include "content/test/test_web_contents.h"
Mario Sanchez Prada2311a9e2019-08-26 14:29:4929#include "mojo/public/cpp/bindings/pending_receiver.h"
30#include "mojo/public/cpp/bindings/pending_remote.h"
31#include "mojo/public/cpp/bindings/receiver.h"
32#include "mojo/public/cpp/bindings/remote.h"
imcheng9f515d02015-02-10 20:09:2433#include "testing/gmock/include/gmock/gmock.h"
34
imcheng9f515d02015-02-10 20:09:2435namespace content {
36
imcheng2ed5f8202015-04-24 19:41:1737namespace {
38
mfoltzfcad52622016-09-03 03:08:3339const char kPresentationId[] = "presentationId";
40const char kPresentationUrl1[] = "http://foo.com/index.html";
41const char kPresentationUrl2[] = "http://example.com/index.html";
mfoltz7a2c823b2016-10-08 01:35:2442const char kPresentationUrl3[] = "http://example.net/index.html";
haibinlu4ba40192015-06-23 21:43:0943
imcheng2ed5f8202015-04-24 19:41:1744} // namespace
45
imcheng9f515d02015-02-10 20:09:2446class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
47 public:
mfoltz7a2c823b2016-10-08 01:35:2448 PresentationServiceImplTest()
49 : presentation_url1_(GURL(kPresentationUrl1)),
50 presentation_url2_(GURL(kPresentationUrl2)),
51 presentation_url3_(GURL(kPresentationUrl3)) {}
imcheng9f515d02015-02-10 20:09:2452
53 void SetUp() override {
54 RenderViewHostImplTestHarness::SetUp();
Avi Drissman650a39d12020-07-14 17:18:2955 // This needed to keep the WebContentsObserverConsistencyChecker checks
56 // happy for when AppendChild is called.
jam5fdbb582017-02-06 22:09:5957 NavigateAndCommit(GURL("about:blank"));
imcheng9f515d02015-02-10 20:09:2458
imcheng2ed5f8202015-04-24 19:41:1759 EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1);
imchengad59d852016-04-21 20:05:0660 TestRenderFrameHost* render_frame_host = contents()->GetMainFrame();
61 render_frame_host->InitializeRenderFrameIfNeeded();
imcheng16819b92015-04-03 08:52:4562 service_impl_.reset(new PresentationServiceImpl(
zhaobinf3704f82017-01-12 07:19:3663 render_frame_host, contents(), &mock_delegate_, nullptr));
imcheng9ce5394b2015-05-12 19:27:0164
Mario Sanchez Prada2ae29e5a2019-08-26 14:42:2365 mojo::PendingRemote<PresentationController> presentation_controller_remote;
66 controller_receiver_.emplace(
67 &mock_controller_,
68 presentation_controller_remote.InitWithNewPipeAndPassReceiver());
69 service_impl_->SetController(std::move(presentation_controller_remote));
mfoltz7a2c823b2016-10-08 01:35:2470
71 presentation_urls_.push_back(presentation_url1_);
72 presentation_urls_.push_back(presentation_url2_);
mark a. foltzd9d2a4512018-04-16 20:42:4573
74 expect_presentation_success_cb_ =
75 base::BindOnce(&PresentationServiceImplTest::ExpectPresentationSuccess,
76 base::Unretained(this));
77 expect_presentation_error_cb_ =
78 base::BindOnce(&PresentationServiceImplTest::ExpectPresentationError,
79 base::Unretained(this));
imcheng9f515d02015-02-10 20:09:2480 }
81
82 void TearDown() override {
imcheng16819b92015-04-03 08:52:4583 if (service_impl_.get()) {
Derek Cheng4de47c52017-10-10 01:05:5484 ExpectDelegateReset();
imcheng2ed5f8202015-04-24 19:41:1785 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
imcheng16819b92015-04-03 08:52:4586 service_impl_.reset();
87 }
imcheng9f515d02015-02-10 20:09:2488 RenderViewHostImplTestHarness::TearDown();
89 }
90
jam5fdbb582017-02-06 22:09:5991 void Navigate(bool main_frame) {
mfoltz0dc2a6b2017-03-07 18:24:1992 RenderFrameHost* rfh = main_rfh();
93 RenderFrameHostTester* rfh_tester = RenderFrameHostTester::For(rfh);
jam5fdbb582017-02-06 22:09:5994 if (!main_frame)
95 rfh = rfh_tester->AppendChild("subframe");
Camille Lamyfa5767c2019-01-07 14:53:5996 MockNavigationHandle handle(GURL(), rfh);
97 handle.set_has_committed(true);
98 service_impl_->DidFinishNavigation(&handle);
jam5fdbb582017-02-06 22:09:5999 }
100
mfoltz7a2c823b2016-10-08 01:35:24101 void ListenForScreenAvailabilityAndWait(const GURL& url,
tapted8f125bdd2016-08-01 04:51:09102 bool delegate_success) {
mlamouri0c8ce522015-10-02 21:47:38103 EXPECT_CALL(mock_delegate_, AddScreenAvailabilityListener())
imchengfafb67d02017-06-15 17:30:14104 .WillOnce(Return(delegate_success));
105 service_impl_->ListenForScreenAvailability(url);
imcheng9f515d02015-02-10 20:09:24106
107 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
108 }
109
Anton Vayvode3c39862017-06-20 20:53:32110 void SimulateScreenAvailabilityChangeAndWait(
111 const GURL& url,
112 ScreenAvailability availability) {
mfoltz3f30502f2015-08-11 16:13:38113 auto listener_it = service_impl_->screen_availability_listeners_.find(url);
114 ASSERT_TRUE(listener_it->second);
imcheng9f515d02015-02-10 20:09:24115
Derek Chengf8ffbec52017-12-06 19:43:04116 EXPECT_CALL(mock_controller_,
117 OnScreenAvailabilityUpdated(url, availability));
Anton Vayvode3c39862017-06-20 20:53:32118 listener_it->second->OnScreenAvailabilityChanged(availability);
imchengfafb67d02017-06-15 17:30:14119 base::RunLoop().RunUntilIdle();
imcheng9f515d02015-02-10 20:09:24120 }
121
Derek Cheng4de47c52017-10-10 01:05:54122 void ExpectDelegateReset() {
imcheng2ed5f8202015-04-24 19:41:17123 EXPECT_CALL(mock_delegate_, Reset(_, _)).Times(1);
imcheng271b9ef2015-03-18 19:43:19124 }
125
126 void ExpectCleanState() {
mfoltzfcad52622016-09-03 03:08:33127 EXPECT_TRUE(service_impl_->default_presentation_urls_.empty());
mfoltz3f30502f2015-08-11 16:13:38128 EXPECT_EQ(
mfoltz7a2c823b2016-10-08 01:35:24129 service_impl_->screen_availability_listeners_.find(presentation_url1_),
mfoltz3f30502f2015-08-11 16:13:38130 service_impl_->screen_availability_listeners_.end());
imcheng271b9ef2015-03-18 19:43:19131 }
132
btolsch8ca10fb22018-08-29 01:35:09133 void ExpectPresentationSuccess(PresentationConnectionResultPtr result,
mark a. foltz756d07e2018-07-20 20:59:18134 PresentationErrorPtr error) {
btolsch8ca10fb22018-08-29 01:35:09135 EXPECT_TRUE(result);
136 EXPECT_FALSE(error);
mark a. foltzd9d2a4512018-04-16 20:42:45137 presentation_cb_was_run_ = true;
138 }
139
btolsch8ca10fb22018-08-29 01:35:09140 void ExpectPresentationError(PresentationConnectionResultPtr result,
mark a. foltz756d07e2018-07-20 20:59:18141 PresentationErrorPtr error) {
btolsch8ca10fb22018-08-29 01:35:09142 EXPECT_FALSE(result);
143 EXPECT_TRUE(error);
mark a. foltzd9d2a4512018-04-16 20:42:45144 presentation_cb_was_run_ = true;
145 }
146
147 void ExpectPresentationCallbackWasRun() const {
148 EXPECT_TRUE(presentation_cb_was_run_)
149 << "ExpectPresentationSuccess or ExpectPresentationError was called";
150 }
151
imcheng9f515d02015-02-10 20:09:24152 MockPresentationServiceDelegate mock_delegate_;
zhaobinf3704f82017-01-12 07:19:36153 MockReceiverPresentationServiceDelegate mock_receiver_delegate_;
imcheng9ce5394b2015-05-12 19:27:01154
dcheng59716272016-04-09 05:19:08155 std::unique_ptr<PresentationServiceImpl> service_impl_;
imcheng9ce5394b2015-05-12 19:27:01156
Derek Chengf8ffbec52017-12-06 19:43:04157 MockPresentationController mock_controller_;
Mario Sanchez Prada2ae29e5a2019-08-26 14:42:23158 base::Optional<mojo::Receiver<PresentationController>> controller_receiver_;
imcheng9ce5394b2015-05-12 19:27:01159
mfoltz7a2c823b2016-10-08 01:35:24160 GURL presentation_url1_;
161 GURL presentation_url2_;
162 GURL presentation_url3_;
163 std::vector<GURL> presentation_urls_;
mark a. foltzd9d2a4512018-04-16 20:42:45164
165 NewPresentationCallback expect_presentation_success_cb_;
166 NewPresentationCallback expect_presentation_error_cb_;
167 bool presentation_cb_was_run_ = false;
imcheng9f515d02015-02-10 20:09:24168};
169
avayvod9b5dbea42015-03-25 18:52:38170TEST_F(PresentationServiceImplTest, ListenForScreenAvailability) {
mfoltz7a2c823b2016-10-08 01:35:24171 ListenForScreenAvailabilityAndWait(presentation_url1_, true);
imcheng9f515d02015-02-10 20:09:24172
Anton Vayvode3c39862017-06-20 20:53:32173 SimulateScreenAvailabilityChangeAndWait(presentation_url1_,
174 ScreenAvailability::AVAILABLE);
175 SimulateScreenAvailabilityChangeAndWait(presentation_url1_,
176 ScreenAvailability::UNAVAILABLE);
177 SimulateScreenAvailabilityChangeAndWait(presentation_url1_,
178 ScreenAvailability::AVAILABLE);
imcheng9f515d02015-02-10 20:09:24179}
180
imchengfafb67d02017-06-15 17:30:14181TEST_F(PresentationServiceImplTest, ScreenAvailabilityNotSupported) {
182 mock_delegate_.set_screen_availability_listening_supported(false);
Derek Chengf8ffbec52017-12-06 19:43:04183 EXPECT_CALL(mock_controller_,
Anton Vayvodddd1c408d2017-06-20 20:54:59184 OnScreenAvailabilityUpdated(presentation_url1_,
185 ScreenAvailability::DISABLED));
imchengfafb67d02017-06-15 17:30:14186 ListenForScreenAvailabilityAndWait(presentation_url1_, false);
187 base::RunLoop().RunUntilIdle();
188}
189
Derek Cheng4de47c52017-10-10 01:05:54190TEST_F(PresentationServiceImplTest, OnDelegateDestroyed) {
mfoltz7a2c823b2016-10-08 01:35:24191 ListenForScreenAvailabilityAndWait(presentation_url1_, true);
imcheng9f515d02015-02-10 20:09:24192
Derek Cheng4de47c52017-10-10 01:05:54193 service_impl_->OnDelegateDestroyed();
194
195 // TearDown() expects |mock_delegate_| to have been notified when
196 // |service_impl_| is destroyed; this does not apply here since the delegate
197 // is destroyed first.
198 service_impl_.reset();
imcheng9f515d02015-02-10 20:09:24199}
200
201TEST_F(PresentationServiceImplTest, DidNavigateThisFrame) {
mfoltz7a2c823b2016-10-08 01:35:24202 ListenForScreenAvailabilityAndWait(presentation_url1_, true);
imcheng9f515d02015-02-10 20:09:24203
Derek Cheng4de47c52017-10-10 01:05:54204 ExpectDelegateReset();
jam5fdbb582017-02-06 22:09:59205 Navigate(true);
imcheng271b9ef2015-03-18 19:43:19206 ExpectCleanState();
imcheng9f515d02015-02-10 20:09:24207}
208
imcheng9ce5394b2015-05-12 19:27:01209TEST_F(PresentationServiceImplTest, DidNavigateOtherFrame) {
mfoltz7a2c823b2016-10-08 01:35:24210 ListenForScreenAvailabilityAndWait(presentation_url1_, true);
imcheng9f515d02015-02-10 20:09:24211
jam5fdbb582017-02-06 22:09:59212 Navigate(false);
imcheng9f515d02015-02-10 20:09:24213
214 // Availability is reported and callback is invoked since it was not
215 // removed.
Anton Vayvode3c39862017-06-20 20:53:32216 SimulateScreenAvailabilityChangeAndWait(presentation_url1_,
217 ScreenAvailability::AVAILABLE);
imcheng9f515d02015-02-10 20:09:24218}
219
imcheng9f515d02015-02-10 20:09:24220TEST_F(PresentationServiceImplTest, DelegateFails) {
mfoltz7a2c823b2016-10-08 01:35:24221 ListenForScreenAvailabilityAndWait(presentation_url1_, false);
mfoltz3f30502f2015-08-11 16:13:38222 ASSERT_EQ(
imchengfafb67d02017-06-15 17:30:14223 service_impl_->screen_availability_listeners_.end(),
224 service_impl_->screen_availability_listeners_.find(presentation_url1_));
imcheng9f515d02015-02-10 20:09:24225}
226
mfoltzfcad52622016-09-03 03:08:33227TEST_F(PresentationServiceImplTest, SetDefaultPresentationUrls) {
Derek Cheng1071a232017-07-25 22:23:56228 EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrls(
229 PresentationUrlsAre(presentation_urls_), _))
imcheng271b9ef2015-03-18 19:43:19230 .Times(1);
imcheng271b9ef2015-03-18 19:43:19231
mfoltz7a2c823b2016-10-08 01:35:24232 service_impl_->SetDefaultPresentationUrls(presentation_urls_);
mfoltzfcad52622016-09-03 03:08:33233
234 // Sets different DPUs.
mfoltz7a2c823b2016-10-08 01:35:24235 std::vector<GURL> more_urls = presentation_urls_;
236 more_urls.push_back(presentation_url3_);
mfoltzfcad52622016-09-03 03:08:33237
mfoltz11fc4df82017-03-20 23:49:18238 PresentationConnectionCallback callback;
Derek Cheng1071a232017-07-25 22:23:56239 EXPECT_CALL(mock_delegate_,
240 SetDefaultPresentationUrls(PresentationUrlsAre(more_urls), _))
241 .WillOnce(SaveArgByMove<1>(&callback));
mfoltz7a2c823b2016-10-08 01:35:24242 service_impl_->SetDefaultPresentationUrls(more_urls);
imchengfa43aae02015-11-11 17:28:44243
mfoltz11fc4df82017-03-20 23:49:18244 PresentationInfo presentation_info(presentation_url2_, kPresentationId);
mfoltz7a2c823b2016-10-08 01:35:24245
btolsch8ca10fb22018-08-29 01:35:09246 EXPECT_CALL(mock_controller_, OnDefaultPresentationStarted(_))
247 .WillOnce([&presentation_info](PresentationConnectionResultPtr result) {
248 EXPECT_THAT(*result->presentation_info, InfoEquals(presentation_info));
249 });
mfoltz7a2c823b2016-10-08 01:35:24250 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _));
btolsch8ca10fb22018-08-29 01:35:09251
Mario Sanchez Prada23a91b22019-08-26 14:45:33252 mojo::PendingRemote<PresentationConnection> presentation_connection_remote;
Mario Sanchez Prada2311a9e2019-08-26 14:29:49253 mojo::Remote<PresentationConnection> controller_remote;
Mario Sanchez Prada23a91b22019-08-26 14:45:33254 ignore_result(
255 presentation_connection_remote.InitWithNewPipeAndPassReceiver());
btolsch8ca10fb22018-08-29 01:35:09256 std::move(callback).Run(PresentationConnectionResult::New(
257 blink::mojom::PresentationInfo::New(presentation_url2_, kPresentationId),
Mario Sanchez Prada23a91b22019-08-26 14:45:33258 std::move(presentation_connection_remote),
Mario Sanchez Prada2311a9e2019-08-26 14:29:49259 controller_remote.BindNewPipeAndPassReceiver()));
imchengfafb67d02017-06-15 17:30:14260 base::RunLoop().RunUntilIdle();
imcheng271b9ef2015-03-18 19:43:19261}
262
imcheng22578da2017-07-11 23:09:11263TEST_F(PresentationServiceImplTest,
264 SetDefaultPresentationUrlsNoopsOnNonMainFrame) {
265 RenderFrameHost* rfh = main_rfh();
266 RenderFrameHostTester* rfh_tester = RenderFrameHostTester::For(rfh);
267 rfh = rfh_tester->AppendChild("subframe");
268
269 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
270 EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1);
271 service_impl_.reset(
272 new PresentationServiceImpl(rfh, contents(), &mock_delegate_, nullptr));
273
Derek Cheng1071a232017-07-25 22:23:56274 EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrls(_, _)).Times(0);
imcheng22578da2017-07-11 23:09:11275 service_impl_->SetDefaultPresentationUrls(presentation_urls_);
276}
277
zhaobin42407c72017-02-07 02:04:16278TEST_F(PresentationServiceImplTest, ListenForConnectionStateChange) {
mfoltz11fc4df82017-03-20 23:49:18279 PresentationInfo connection(presentation_url1_, kPresentationId);
mfoltz0dc2a6b2017-03-07 18:24:19280 PresentationConnectionStateChangedCallback state_changed_cb;
Derek Chengf8ffbec52017-12-06 19:43:04281 // Trigger state change. It should be propagated back up to
282 // |mock_controller_|.
mfoltz11fc4df82017-03-20 23:49:18283 PresentationInfo presentation_connection(presentation_url1_, kPresentationId);
zhaobinbadd5952016-11-09 18:25:50284
285 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
286 .WillOnce(SaveArg<3>(&state_changed_cb));
imcheng1ebdd162017-01-26 22:01:52287 service_impl_->ListenForConnectionStateChange(connection);
zhaobinbadd5952016-11-09 18:25:50288
mark a. foltz756d07e2018-07-20 20:59:18289 EXPECT_CALL(mock_controller_, OnConnectionStateChanged(
290 InfoPtrEquals(presentation_connection),
mark a. foltze8ad3202018-04-23 22:50:23291 PresentationConnectionState::TERMINATED));
imchengfafb67d02017-06-15 17:30:14292 state_changed_cb.Run(PresentationConnectionStateChangeInfo(
mark a. foltze8ad3202018-04-23 22:50:23293 PresentationConnectionState::TERMINATED));
imchengfafb67d02017-06-15 17:30:14294 base::RunLoop().RunUntilIdle();
imchenged10e962016-02-23 06:34:44295}
296
297TEST_F(PresentationServiceImplTest, ListenForConnectionClose) {
mfoltz11fc4df82017-03-20 23:49:18298 PresentationInfo connection(presentation_url1_, kPresentationId);
mfoltz0dc2a6b2017-03-07 18:24:19299 PresentationConnectionStateChangedCallback state_changed_cb;
imchenged10e962016-02-23 06:34:44300 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
301 .WillOnce(SaveArg<3>(&state_changed_cb));
imcheng1ebdd162017-01-26 22:01:52302 service_impl_->ListenForConnectionStateChange(connection);
imchenged10e962016-02-23 06:34:44303
304 // Trigger connection close. It should be propagated back up to
Derek Chengf8ffbec52017-12-06 19:43:04305 // |mock_controller_|.
mfoltz11fc4df82017-03-20 23:49:18306 PresentationInfo presentation_connection(presentation_url1_, kPresentationId);
imchengfafb67d02017-06-15 17:30:14307 PresentationConnectionStateChangeInfo closed_info(
mark a. foltze8ad3202018-04-23 22:50:23308 PresentationConnectionState::CLOSED);
mark a. foltzd9d2a4512018-04-16 20:42:45309 closed_info.close_reason = PresentationConnectionCloseReason::WENT_AWAY;
imchengfafb67d02017-06-15 17:30:14310 closed_info.message = "Foo";
imchenged10e962016-02-23 06:34:44311
mark a. foltz756d07e2018-07-20 20:59:18312 EXPECT_CALL(
313 mock_controller_,
314 OnConnectionClosed(InfoPtrEquals(presentation_connection),
315 PresentationConnectionCloseReason::WENT_AWAY, "Foo"));
imchengfafb67d02017-06-15 17:30:14316 state_changed_cb.Run(closed_info);
317 base::RunLoop().RunUntilIdle();
imchengf3e5a012015-11-20 04:08:37318}
319
mfoltzfcad52622016-09-03 03:08:33320TEST_F(PresentationServiceImplTest, SetSameDefaultPresentationUrls) {
Derek Cheng1071a232017-07-25 22:23:56321 EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrls(_, _)).Times(1);
mfoltz7a2c823b2016-10-08 01:35:24322 service_impl_->SetDefaultPresentationUrls(presentation_urls_);
imcheng271b9ef2015-03-18 19:43:19323 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
mfoltzfcad52622016-09-03 03:08:33324
325 // Same URLs as before; no-ops.
mfoltz7a2c823b2016-10-08 01:35:24326 service_impl_->SetDefaultPresentationUrls(presentation_urls_);
mfoltzfcad52622016-09-03 03:08:33327 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
imcheng271b9ef2015-03-18 19:43:19328}
329
mfoltz11fc4df82017-03-20 23:49:18330TEST_F(PresentationServiceImplTest, StartPresentationSuccess) {
btolsch8ca10fb22018-08-29 01:35:09331 PresentationConnectionCallback saved_success_cb;
mark a. foltz756d07e2018-07-20 20:59:18332 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, _))
btolsch8ca10fb22018-08-29 01:35:09333 .WillOnce([&saved_success_cb](const auto& request, auto success_cb,
334 auto error_cb) {
mark a. foltz756d07e2018-07-20 20:59:18335 saved_success_cb = std::move(success_cb);
336 });
imchengfafb67d02017-06-15 17:30:14337 service_impl_->StartPresentation(presentation_urls_,
mark a. foltzd9d2a4512018-04-16 20:42:45338 std::move(expect_presentation_success_cb_));
mark a. foltz756d07e2018-07-20 20:59:18339 EXPECT_FALSE(saved_success_cb.is_null());
imchengf3e5a012015-11-20 04:08:37340 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
341 .Times(1);
mark a. foltz756d07e2018-07-20 20:59:18342 std::move(saved_success_cb)
btolsch8ca10fb22018-08-29 01:35:09343 .Run(PresentationConnectionResult::New(
344 blink::mojom::PresentationInfo::New(presentation_url1_,
345 kPresentationId),
Mario Sanchez Prada2311a9e2019-08-26 14:29:49346 mojo::NullRemote(), mojo::NullReceiver()));
mark a. foltzd9d2a4512018-04-16 20:42:45347 ExpectPresentationCallbackWasRun();
imcheng271b9ef2015-03-18 19:43:19348}
349
mfoltz11fc4df82017-03-20 23:49:18350TEST_F(PresentationServiceImplTest, StartPresentationError) {
mark a. foltz756d07e2018-07-20 20:59:18351 base::OnceCallback<void(const PresentationError&)> saved_error_cb;
352 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, _))
353 .WillOnce([&](const auto& request, auto success_cb, auto error_cb) {
354 saved_error_cb = std::move(error_cb);
355 });
imchengfafb67d02017-06-15 17:30:14356 service_impl_->StartPresentation(presentation_urls_,
mark a. foltzd9d2a4512018-04-16 20:42:45357 std::move(expect_presentation_error_cb_));
mark a. foltz756d07e2018-07-20 20:59:18358 EXPECT_FALSE(saved_error_cb.is_null());
359 std::move(saved_error_cb)
360 .Run(PresentationError(PresentationErrorType::UNKNOWN, "Error message"));
mark a. foltzd9d2a4512018-04-16 20:42:45361 ExpectPresentationCallbackWasRun();
imchengfafb67d02017-06-15 17:30:14362}
363
364TEST_F(PresentationServiceImplTest, StartPresentationInProgress) {
mark a. foltz756d07e2018-07-20 20:59:18365 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, _)).Times(1);
imchengfafb67d02017-06-15 17:30:14366 // Uninvoked callbacks must outlive |service_impl_| since they get invoked
367 // at |service_impl_|'s destruction.
Peter Kasting341e1fb2018-02-24 00:03:01368 service_impl_->StartPresentation(presentation_urls_, base::DoNothing());
imchengfafb67d02017-06-15 17:30:14369
370 // This request should fail immediately, since there is already a
371 // StartPresentation in progress.
imchengfafb67d02017-06-15 17:30:14372 service_impl_->StartPresentation(presentation_urls_,
mark a. foltzd9d2a4512018-04-16 20:42:45373 std::move(expect_presentation_error_cb_));
374 ExpectPresentationCallbackWasRun();
imcheng271b9ef2015-03-18 19:43:19375}
376
mfoltz11fc4df82017-03-20 23:49:18377TEST_F(PresentationServiceImplTest, ReconnectPresentationSuccess) {
btolsch8ca10fb22018-08-29 01:35:09378 PresentationConnectionCallback saved_success_cb;
mark a. foltz756d07e2018-07-20 20:59:18379 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, kPresentationId, _, _))
btolsch8ca10fb22018-08-29 01:35:09380 .WillOnce([&saved_success_cb](const auto& request, const auto& id,
381 auto success_cb, auto error_cb) {
382 saved_success_cb = std::move(success_cb);
383 });
mark a. foltzd9d2a4512018-04-16 20:42:45384 service_impl_->ReconnectPresentation(
385 presentation_urls_, kPresentationId,
386 std::move(expect_presentation_success_cb_));
mark a. foltz756d07e2018-07-20 20:59:18387 EXPECT_FALSE(saved_success_cb.is_null());
imchengf3e5a012015-11-20 04:08:37388 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
389 .Times(1);
mark a. foltz756d07e2018-07-20 20:59:18390 std::move(saved_success_cb)
btolsch8ca10fb22018-08-29 01:35:09391 .Run(PresentationConnectionResult::New(
392 blink::mojom::PresentationInfo::New(presentation_url1_,
393 kPresentationId),
Mario Sanchez Prada2311a9e2019-08-26 14:29:49394 mojo::NullRemote(), mojo::NullReceiver()));
mark a. foltzd9d2a4512018-04-16 20:42:45395 ExpectPresentationCallbackWasRun();
imcheng271b9ef2015-03-18 19:43:19396}
397
mfoltz11fc4df82017-03-20 23:49:18398TEST_F(PresentationServiceImplTest, ReconnectPresentationError) {
mark a. foltz756d07e2018-07-20 20:59:18399 base::OnceCallback<void(const PresentationError&)> saved_error_cb;
400 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, kPresentationId, _, _))
401 .WillOnce([&](const auto& request, const std::string& id, auto success_cb,
402 auto error_cb) { saved_error_cb = std::move(error_cb); });
mark a. foltzd9d2a4512018-04-16 20:42:45403 service_impl_->ReconnectPresentation(
404 presentation_urls_, kPresentationId,
405 std::move(expect_presentation_error_cb_));
mark a. foltz756d07e2018-07-20 20:59:18406 EXPECT_FALSE(saved_error_cb.is_null());
407 std::move(saved_error_cb)
408 .Run(PresentationError(PresentationErrorType::UNKNOWN, "Error message"));
mark a. foltzd9d2a4512018-04-16 20:42:45409 ExpectPresentationCallbackWasRun();
imchengfafb67d02017-06-15 17:30:14410}
411
412TEST_F(PresentationServiceImplTest, MaxPendingReconnectPresentationRequests) {
413 const char* presentation_url = "http://fooUrl%d";
414 const char* presentation_id = "presentationId%d";
415 int num_requests = PresentationServiceImpl::kMaxQueuedRequests;
416 int i = 0;
mark a. foltz756d07e2018-07-20 20:59:18417 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, _, _))
imchengfafb67d02017-06-15 17:30:14418 .Times(num_requests);
419 for (; i < num_requests; ++i) {
420 std::vector<GURL> urls = {GURL(base::StringPrintf(presentation_url, i))};
421 // Uninvoked callbacks must outlive |service_impl_| since they get invoked
422 // at |service_impl_|'s destruction.
Peter Kasting341e1fb2018-02-24 00:03:01423 service_impl_->ReconnectPresentation(
424 urls, base::StringPrintf(presentation_id, i), base::DoNothing());
imchengfafb67d02017-06-15 17:30:14425 }
426
427 std::vector<GURL> urls = {GURL(base::StringPrintf(presentation_url, i))};
428 // Exceeded maximum queue size, should invoke mojo callback with error.
imchengfafb67d02017-06-15 17:30:14429 service_impl_->ReconnectPresentation(
mark a. foltzd9d2a4512018-04-16 20:42:45430 urls, base::StringPrintf(presentation_id, i),
431 std::move(expect_presentation_error_cb_));
432 ExpectPresentationCallbackWasRun();
imcheng271b9ef2015-03-18 19:43:19433}
434
mfoltzd0c3de12015-12-12 04:43:08435TEST_F(PresentationServiceImplTest, CloseConnection) {
imchengfafb67d02017-06-15 17:30:14436 EXPECT_CALL(mock_delegate_, CloseConnection(_, _, Eq(kPresentationId)));
437 service_impl_->CloseConnection(presentation_url1_, kPresentationId);
haibinlu4ba40192015-06-23 21:43:09438}
439
mfoltzd0c3de12015-12-12 04:43:08440TEST_F(PresentationServiceImplTest, Terminate) {
imchengfafb67d02017-06-15 17:30:14441 EXPECT_CALL(mock_delegate_, Terminate(_, _, Eq(kPresentationId)));
442 service_impl_->Terminate(presentation_url1_, kPresentationId);
mlamouric65a70d72015-11-27 16:28:59443}
444
zhaobinf3704f82017-01-12 07:19:36445TEST_F(PresentationServiceImplTest, ReceiverPresentationServiceDelegate) {
zhaobindca98f632017-06-29 18:42:28446 EXPECT_CALL(mock_receiver_delegate_, AddObserver(_, _, _)).Times(1);
zhaobinf3704f82017-01-12 07:19:36447
imchengfafb67d02017-06-15 17:30:14448 PresentationServiceImpl service_impl(main_rfh(), contents(), nullptr,
zhaobindca98f632017-06-29 18:42:28449 &mock_receiver_delegate_);
zhaobinf3704f82017-01-12 07:19:36450
451 ReceiverConnectionAvailableCallback callback;
zhaobindca98f632017-06-29 18:42:28452 EXPECT_CALL(mock_receiver_delegate_,
zhaobinf3704f82017-01-12 07:19:36453 RegisterReceiverConnectionAvailableCallback(_))
454 .WillOnce(SaveArg<0>(&callback));
455
Derek Cheng4de47c52017-10-10 01:05:54456 MockPresentationReceiver mock_receiver;
Mario Sanchez Prada23a91b22019-08-26 14:45:33457 mojo::Receiver<blink::mojom::PresentationReceiver>
458 presentation_receiver_receiver(&mock_receiver);
459 service_impl.SetReceiver(
460 presentation_receiver_receiver.BindNewPipeAndPassRemote());
zhaobinf3704f82017-01-12 07:19:36461 EXPECT_FALSE(callback.is_null());
462
mark a. foltze2084383c2018-05-11 19:21:50463 PresentationInfo expected(presentation_url1_, kPresentationId);
zhaobinf3704f82017-01-12 07:19:36464
imchengfafb67d02017-06-15 17:30:14465 // Client gets notified of receiver connections.
Mario Sanchez Prada2311a9e2019-08-26 14:29:49466 mojo::PendingRemote<PresentationConnection> controller_connection;
imchengfafb67d02017-06-15 17:30:14467 MockPresentationConnection mock_presentation_connection;
Mario Sanchez Prada2311a9e2019-08-26 14:29:49468 mojo::Receiver<PresentationConnection> connection_binding(
469 &mock_presentation_connection,
470 controller_connection.InitWithNewPipeAndPassReceiver());
471 mojo::Remote<PresentationConnection> receiver_connection;
Derek Cheng4de47c52017-10-10 01:05:54472
473 EXPECT_CALL(mock_receiver,
mark a. foltz756d07e2018-07-20 20:59:18474 OnReceiverConnectionAvailable(InfoPtrEquals(expected), _, _))
Derek Cheng4de47c52017-10-10 01:05:54475 .Times(1);
mark a. foltze2084383c2018-05-11 19:21:50476 callback.Run(PresentationInfo::New(expected),
477 std::move(controller_connection),
Mario Sanchez Prada2311a9e2019-08-26 14:29:49478 receiver_connection.BindNewPipeAndPassReceiver());
imchengfafb67d02017-06-15 17:30:14479 base::RunLoop().RunUntilIdle();
480
zhaobindca98f632017-06-29 18:42:28481 EXPECT_CALL(mock_receiver_delegate_, RemoveObserver(_, _)).Times(1);
482}
483
484TEST_F(PresentationServiceImplTest, ReceiverDelegateOnSubFrame) {
485 EXPECT_CALL(mock_receiver_delegate_, AddObserver(_, _, _)).Times(1);
486
487 PresentationServiceImpl service_impl(main_rfh(), contents(), nullptr,
488 &mock_receiver_delegate_);
489 service_impl.is_main_frame_ = false;
490
491 ReceiverConnectionAvailableCallback callback;
492 EXPECT_CALL(mock_receiver_delegate_,
493 RegisterReceiverConnectionAvailableCallback(_))
494 .Times(0);
495
Mario Sanchez Prada2ae29e5a2019-08-26 14:42:23496 mojo::PendingRemote<PresentationController> presentation_controller_remote;
497 controller_receiver_.emplace(
498 &mock_controller_,
499 presentation_controller_remote.InitWithNewPipeAndPassReceiver());
zhaobindca98f632017-06-29 18:42:28500 service_impl.controller_delegate_ = nullptr;
Mario Sanchez Prada2ae29e5a2019-08-26 14:42:23501 service_impl.SetController(std::move(presentation_controller_remote));
zhaobindca98f632017-06-29 18:42:28502
503 EXPECT_CALL(mock_receiver_delegate_, Reset(_, _)).Times(0);
504 service_impl.Reset();
505
506 EXPECT_CALL(mock_receiver_delegate_, RemoveObserver(_, _)).Times(1);
mlamouri0c8ce522015-10-02 21:47:38507}
508
imcheng9f515d02015-02-10 20:09:24509} // namespace content