blob: 4887a4f2633b2566eeaa1e528ccb1356b2f12f4a [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2015 The Chromium Authors
imcheng9f515d02015-02-10 20:09:242// 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>
Arthur Sonzognic686e8f2024-01-11 08:36:3712#include <optional>
kmarshallf5367c642015-08-20 19:23:1313#include <string>
Avi Drissman5d5d48d62022-01-07 20:23:5814#include <tuple>
dcheng36b6aec92015-12-26 06:16:3615#include <utility>
kmarshallf5367c642015-08-20 19:23:1316#include <vector>
17
Avi Drissmanadac21992023-01-11 23:46:3918#include "base/functional/bind.h"
19#include "base/functional/callback_helpers.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 Amnic7bc82632019-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
Wei4 Wange1c8c002023-04-24 23:30:2535using blink::mojom::PresentationConnectionResult;
36using blink::mojom::PresentationInfo;
37
imcheng9f515d02015-02-10 20:09:2438namespace content {
39
imcheng2ed5f8202015-04-24 19:41:1740namespace {
41
mfoltzfcad52622016-09-03 03:08:3342const char kPresentationId[] = "presentationId";
43const char kPresentationUrl1[] = "http://foo.com/index.html";
44const char kPresentationUrl2[] = "http://example.com/index.html";
mfoltz7a2c823b2016-10-08 01:35:2445const char kPresentationUrl3[] = "http://example.net/index.html";
haibinlu4ba40192015-06-23 21:43:0946
imcheng2ed5f8202015-04-24 19:41:1747} // namespace
48
imcheng9f515d02015-02-10 20:09:2449class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
50 public:
mfoltz7a2c823b2016-10-08 01:35:2451 PresentationServiceImplTest()
52 : presentation_url1_(GURL(kPresentationUrl1)),
53 presentation_url2_(GURL(kPresentationUrl2)),
54 presentation_url3_(GURL(kPresentationUrl3)) {}
imcheng9f515d02015-02-10 20:09:2455
56 void SetUp() override {
57 RenderViewHostImplTestHarness::SetUp();
Avi Drissman650a39d12020-07-14 17:18:2958 // This needed to keep the WebContentsObserverConsistencyChecker checks
59 // happy for when AppendChild is called.
jam5fdbb58d2017-02-06 22:09:5960 NavigateAndCommit(GURL("about:blank"));
imcheng9f515d02015-02-10 20:09:2461
imcheng2ed5f8202015-04-24 19:41:1762 EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1);
Dave Tapuska327c06c92022-06-13 20:31:5163 TestRenderFrameHost* render_frame_host = contents()->GetPrimaryMainFrame();
imchengad59d852016-04-21 20:05:0664 render_frame_host->InitializeRenderFrameIfNeeded();
imcheng16819b92015-04-03 08:52:4565 service_impl_.reset(new PresentationServiceImpl(
zhaobinf3704f82017-01-12 07:19:3666 render_frame_host, contents(), &mock_delegate_, nullptr));
imcheng9ce5394b2015-05-12 19:27:0167
Mario Sanchez Prada2ae29e5a2019-08-26 14:42:2368 mojo::PendingRemote<PresentationController> presentation_controller_remote;
69 controller_receiver_.emplace(
70 &mock_controller_,
71 presentation_controller_remote.InitWithNewPipeAndPassReceiver());
72 service_impl_->SetController(std::move(presentation_controller_remote));
mfoltz7a2c823b2016-10-08 01:35:2473
74 presentation_urls_.push_back(presentation_url1_);
75 presentation_urls_.push_back(presentation_url2_);
mark a. foltzd9d2a4512018-04-16 20:42:4576
77 expect_presentation_success_cb_ =
78 base::BindOnce(&PresentationServiceImplTest::ExpectPresentationSuccess,
79 base::Unretained(this));
80 expect_presentation_error_cb_ =
81 base::BindOnce(&PresentationServiceImplTest::ExpectPresentationError,
82 base::Unretained(this));
imcheng9f515d02015-02-10 20:09:2483 }
84
85 void TearDown() override {
imcheng16819b92015-04-03 08:52:4586 if (service_impl_.get()) {
Derek Cheng4de47c52017-10-10 01:05:5487 ExpectDelegateReset();
imcheng2ed5f8202015-04-24 19:41:1788 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
imcheng16819b92015-04-03 08:52:4589 service_impl_.reset();
90 }
imcheng9f515d02015-02-10 20:09:2491 RenderViewHostImplTestHarness::TearDown();
92 }
93
jam5fdbb58d2017-02-06 22:09:5994 void Navigate(bool main_frame) {
mfoltz0dc2a6b2017-03-07 18:24:1995 RenderFrameHost* rfh = main_rfh();
96 RenderFrameHostTester* rfh_tester = RenderFrameHostTester::For(rfh);
jam5fdbb58d2017-02-06 22:09:5997 if (!main_frame)
98 rfh = rfh_tester->AppendChild("subframe");
Camille Lamyfa5767c2019-01-07 14:53:5999 MockNavigationHandle handle(GURL(), rfh);
100 handle.set_has_committed(true);
101 service_impl_->DidFinishNavigation(&handle);
jam5fdbb58d2017-02-06 22:09:59102 }
103
mfoltz7a2c823b2016-10-08 01:35:24104 void ListenForScreenAvailabilityAndWait(const GURL& url,
tapted8f125bdd2016-08-01 04:51:09105 bool delegate_success) {
mlamouri0c8ce522015-10-02 21:47:38106 EXPECT_CALL(mock_delegate_, AddScreenAvailabilityListener())
imchengfafb67d02017-06-15 17:30:14107 .WillOnce(Return(delegate_success));
108 service_impl_->ListenForScreenAvailability(url);
imcheng9f515d02015-02-10 20:09:24109
110 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
111 }
112
Anton Vayvode3c39862017-06-20 20:53:32113 void SimulateScreenAvailabilityChangeAndWait(
114 const GURL& url,
115 ScreenAvailability availability) {
mfoltz3f30502f2015-08-11 16:13:38116 auto listener_it = service_impl_->screen_availability_listeners_.find(url);
117 ASSERT_TRUE(listener_it->second);
imcheng9f515d02015-02-10 20:09:24118
Derek Chengf8ffbec52017-12-06 19:43:04119 EXPECT_CALL(mock_controller_,
120 OnScreenAvailabilityUpdated(url, availability));
Anton Vayvode3c39862017-06-20 20:53:32121 listener_it->second->OnScreenAvailabilityChanged(availability);
imchengfafb67d02017-06-15 17:30:14122 base::RunLoop().RunUntilIdle();
imcheng9f515d02015-02-10 20:09:24123 }
124
Derek Cheng4de47c52017-10-10 01:05:54125 void ExpectDelegateReset() {
imcheng2ed5f8202015-04-24 19:41:17126 EXPECT_CALL(mock_delegate_, Reset(_, _)).Times(1);
imcheng271b9ef2015-03-18 19:43:19127 }
128
129 void ExpectCleanState() {
mfoltzfcad52622016-09-03 03:08:33130 EXPECT_TRUE(service_impl_->default_presentation_urls_.empty());
mfoltz3f30502f2015-08-11 16:13:38131 EXPECT_EQ(
mfoltz7a2c823b2016-10-08 01:35:24132 service_impl_->screen_availability_listeners_.find(presentation_url1_),
mfoltz3f30502f2015-08-11 16:13:38133 service_impl_->screen_availability_listeners_.end());
imcheng271b9ef2015-03-18 19:43:19134 }
135
btolsch8ca10fb22018-08-29 01:35:09136 void ExpectPresentationSuccess(PresentationConnectionResultPtr result,
mark a. foltz756d07e2018-07-20 20:59:18137 PresentationErrorPtr error) {
btolsch8ca10fb22018-08-29 01:35:09138 EXPECT_TRUE(result);
139 EXPECT_FALSE(error);
mark a. foltzd9d2a4512018-04-16 20:42:45140 presentation_cb_was_run_ = true;
141 }
142
btolsch8ca10fb22018-08-29 01:35:09143 void ExpectPresentationError(PresentationConnectionResultPtr result,
mark a. foltz756d07e2018-07-20 20:59:18144 PresentationErrorPtr error) {
btolsch8ca10fb22018-08-29 01:35:09145 EXPECT_FALSE(result);
146 EXPECT_TRUE(error);
mark a. foltzd9d2a4512018-04-16 20:42:45147 presentation_cb_was_run_ = true;
148 }
149
150 void ExpectPresentationCallbackWasRun() const {
151 EXPECT_TRUE(presentation_cb_was_run_)
152 << "ExpectPresentationSuccess or ExpectPresentationError was called";
153 }
154
imcheng9f515d02015-02-10 20:09:24155 MockPresentationServiceDelegate mock_delegate_;
zhaobinf3704f82017-01-12 07:19:36156 MockReceiverPresentationServiceDelegate mock_receiver_delegate_;
imcheng9ce5394b2015-05-12 19:27:01157
dcheng59716272016-04-09 05:19:08158 std::unique_ptr<PresentationServiceImpl> service_impl_;
imcheng9ce5394b2015-05-12 19:27:01159
Derek Chengf8ffbec52017-12-06 19:43:04160 MockPresentationController mock_controller_;
Arthur Sonzognic686e8f2024-01-11 08:36:37161 std::optional<mojo::Receiver<PresentationController>> controller_receiver_;
imcheng9ce5394b2015-05-12 19:27:01162
mfoltz7a2c823b2016-10-08 01:35:24163 GURL presentation_url1_;
164 GURL presentation_url2_;
165 GURL presentation_url3_;
166 std::vector<GURL> presentation_urls_;
mark a. foltzd9d2a4512018-04-16 20:42:45167
168 NewPresentationCallback expect_presentation_success_cb_;
169 NewPresentationCallback expect_presentation_error_cb_;
170 bool presentation_cb_was_run_ = false;
imcheng9f515d02015-02-10 20:09:24171};
172
avayvod9b5dbea42015-03-25 18:52:38173TEST_F(PresentationServiceImplTest, ListenForScreenAvailability) {
mfoltz7a2c823b2016-10-08 01:35:24174 ListenForScreenAvailabilityAndWait(presentation_url1_, true);
imcheng9f515d02015-02-10 20:09:24175
Anton Vayvode3c39862017-06-20 20:53:32176 SimulateScreenAvailabilityChangeAndWait(presentation_url1_,
177 ScreenAvailability::AVAILABLE);
178 SimulateScreenAvailabilityChangeAndWait(presentation_url1_,
179 ScreenAvailability::UNAVAILABLE);
180 SimulateScreenAvailabilityChangeAndWait(presentation_url1_,
181 ScreenAvailability::AVAILABLE);
imcheng9f515d02015-02-10 20:09:24182}
183
imchengfafb67d02017-06-15 17:30:14184TEST_F(PresentationServiceImplTest, ScreenAvailabilityNotSupported) {
185 mock_delegate_.set_screen_availability_listening_supported(false);
Derek Chengf8ffbec52017-12-06 19:43:04186 EXPECT_CALL(mock_controller_,
Anton Vayvodddd1c408d2017-06-20 20:54:59187 OnScreenAvailabilityUpdated(presentation_url1_,
188 ScreenAvailability::DISABLED));
imchengfafb67d02017-06-15 17:30:14189 ListenForScreenAvailabilityAndWait(presentation_url1_, false);
190 base::RunLoop().RunUntilIdle();
191}
192
Derek Cheng4de47c52017-10-10 01:05:54193TEST_F(PresentationServiceImplTest, OnDelegateDestroyed) {
mfoltz7a2c823b2016-10-08 01:35:24194 ListenForScreenAvailabilityAndWait(presentation_url1_, true);
imcheng9f515d02015-02-10 20:09:24195
Derek Cheng4de47c52017-10-10 01:05:54196 service_impl_->OnDelegateDestroyed();
197
198 // TearDown() expects |mock_delegate_| to have been notified when
199 // |service_impl_| is destroyed; this does not apply here since the delegate
200 // is destroyed first.
201 service_impl_.reset();
imcheng9f515d02015-02-10 20:09:24202}
203
204TEST_F(PresentationServiceImplTest, DidNavigateThisFrame) {
mfoltz7a2c823b2016-10-08 01:35:24205 ListenForScreenAvailabilityAndWait(presentation_url1_, true);
imcheng9f515d02015-02-10 20:09:24206
Derek Cheng4de47c52017-10-10 01:05:54207 ExpectDelegateReset();
jam5fdbb58d2017-02-06 22:09:59208 Navigate(true);
imcheng271b9ef2015-03-18 19:43:19209 ExpectCleanState();
imcheng9f515d02015-02-10 20:09:24210}
211
imcheng9ce5394b2015-05-12 19:27:01212TEST_F(PresentationServiceImplTest, DidNavigateOtherFrame) {
mfoltz7a2c823b2016-10-08 01:35:24213 ListenForScreenAvailabilityAndWait(presentation_url1_, true);
imcheng9f515d02015-02-10 20:09:24214
jam5fdbb58d2017-02-06 22:09:59215 Navigate(false);
imcheng9f515d02015-02-10 20:09:24216
217 // Availability is reported and callback is invoked since it was not
218 // removed.
Anton Vayvode3c39862017-06-20 20:53:32219 SimulateScreenAvailabilityChangeAndWait(presentation_url1_,
220 ScreenAvailability::AVAILABLE);
imcheng9f515d02015-02-10 20:09:24221}
222
imcheng9f515d02015-02-10 20:09:24223TEST_F(PresentationServiceImplTest, DelegateFails) {
mfoltz7a2c823b2016-10-08 01:35:24224 ListenForScreenAvailabilityAndWait(presentation_url1_, false);
mfoltz3f30502f2015-08-11 16:13:38225 ASSERT_EQ(
imchengfafb67d02017-06-15 17:30:14226 service_impl_->screen_availability_listeners_.end(),
227 service_impl_->screen_availability_listeners_.find(presentation_url1_));
imcheng9f515d02015-02-10 20:09:24228}
229
mfoltzfcad52622016-09-03 03:08:33230TEST_F(PresentationServiceImplTest, SetDefaultPresentationUrls) {
Derek Cheng1071a232017-07-25 22:23:56231 EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrls(
232 PresentationUrlsAre(presentation_urls_), _))
imcheng271b9ef2015-03-18 19:43:19233 .Times(1);
imcheng271b9ef2015-03-18 19:43:19234
mfoltz7a2c823b2016-10-08 01:35:24235 service_impl_->SetDefaultPresentationUrls(presentation_urls_);
mfoltzfcad52622016-09-03 03:08:33236
237 // Sets different DPUs.
mfoltz7a2c823b2016-10-08 01:35:24238 std::vector<GURL> more_urls = presentation_urls_;
239 more_urls.push_back(presentation_url3_);
mfoltzfcad52622016-09-03 03:08:33240
mfoltz11fc4df82017-03-20 23:49:18241 PresentationConnectionCallback callback;
Derek Cheng1071a232017-07-25 22:23:56242 EXPECT_CALL(mock_delegate_,
243 SetDefaultPresentationUrls(PresentationUrlsAre(more_urls), _))
244 .WillOnce(SaveArgByMove<1>(&callback));
mfoltz7a2c823b2016-10-08 01:35:24245 service_impl_->SetDefaultPresentationUrls(more_urls);
imchengfa43aae02015-11-11 17:28:44246
mfoltz11fc4df82017-03-20 23:49:18247 PresentationInfo presentation_info(presentation_url2_, kPresentationId);
mfoltz7a2c823b2016-10-08 01:35:24248
btolsch8ca10fb22018-08-29 01:35:09249 EXPECT_CALL(mock_controller_, OnDefaultPresentationStarted(_))
250 .WillOnce([&presentation_info](PresentationConnectionResultPtr result) {
251 EXPECT_THAT(*result->presentation_info, InfoEquals(presentation_info));
252 });
mfoltz7a2c823b2016-10-08 01:35:24253 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _));
btolsch8ca10fb22018-08-29 01:35:09254
Mario Sanchez Prada23a91b22019-08-26 14:45:33255 mojo::PendingRemote<PresentationConnection> presentation_connection_remote;
Mario Sanchez Prada2311a9e2019-08-26 14:29:49256 mojo::Remote<PresentationConnection> controller_remote;
Avi Drissman5d5d48d62022-01-07 20:23:58257 std::ignore = presentation_connection_remote.InitWithNewPipeAndPassReceiver();
btolsch8ca10fb22018-08-29 01:35:09258 std::move(callback).Run(PresentationConnectionResult::New(
Wei4 Wange1c8c002023-04-24 23:30:25259 PresentationInfo::New(presentation_url2_, kPresentationId),
Mario Sanchez Prada23a91b22019-08-26 14:45:33260 std::move(presentation_connection_remote),
Mario Sanchez Prada2311a9e2019-08-26 14:29:49261 controller_remote.BindNewPipeAndPassReceiver()));
imchengfafb67d02017-06-15 17:30:14262 base::RunLoop().RunUntilIdle();
imcheng271b9ef2015-03-18 19:43:19263}
264
imcheng22578da2017-07-11 23:09:11265TEST_F(PresentationServiceImplTest,
266 SetDefaultPresentationUrlsNoopsOnNonMainFrame) {
267 RenderFrameHost* rfh = main_rfh();
268 RenderFrameHostTester* rfh_tester = RenderFrameHostTester::For(rfh);
269 rfh = rfh_tester->AppendChild("subframe");
270
271 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
272 EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1);
273 service_impl_.reset(
274 new PresentationServiceImpl(rfh, contents(), &mock_delegate_, nullptr));
275
Derek Cheng1071a232017-07-25 22:23:56276 EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrls(_, _)).Times(0);
imcheng22578da2017-07-11 23:09:11277 service_impl_->SetDefaultPresentationUrls(presentation_urls_);
278}
279
zhaobin42407c72017-02-07 02:04:16280TEST_F(PresentationServiceImplTest, ListenForConnectionStateChange) {
mfoltz11fc4df82017-03-20 23:49:18281 PresentationInfo connection(presentation_url1_, kPresentationId);
mfoltz0dc2a6b2017-03-07 18:24:19282 PresentationConnectionStateChangedCallback state_changed_cb;
Derek Chengf8ffbec52017-12-06 19:43:04283 // Trigger state change. It should be propagated back up to
284 // |mock_controller_|.
mfoltz11fc4df82017-03-20 23:49:18285 PresentationInfo presentation_connection(presentation_url1_, kPresentationId);
zhaobinbadd5952016-11-09 18:25:50286
287 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
288 .WillOnce(SaveArg<3>(&state_changed_cb));
imcheng1ebdd162017-01-26 22:01:52289 service_impl_->ListenForConnectionStateChange(connection);
zhaobinbadd5952016-11-09 18:25:50290
mark a. foltz756d07e2018-07-20 20:59:18291 EXPECT_CALL(mock_controller_, OnConnectionStateChanged(
292 InfoPtrEquals(presentation_connection),
mark a. foltze8ad3202018-04-23 22:50:23293 PresentationConnectionState::TERMINATED));
imchengfafb67d02017-06-15 17:30:14294 state_changed_cb.Run(PresentationConnectionStateChangeInfo(
mark a. foltze8ad3202018-04-23 22:50:23295 PresentationConnectionState::TERMINATED));
imchengfafb67d02017-06-15 17:30:14296 base::RunLoop().RunUntilIdle();
imchenged10e962016-02-23 06:34:44297}
298
299TEST_F(PresentationServiceImplTest, ListenForConnectionClose) {
mfoltz11fc4df82017-03-20 23:49:18300 PresentationInfo connection(presentation_url1_, kPresentationId);
mfoltz0dc2a6b2017-03-07 18:24:19301 PresentationConnectionStateChangedCallback state_changed_cb;
imchenged10e962016-02-23 06:34:44302 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
303 .WillOnce(SaveArg<3>(&state_changed_cb));
imcheng1ebdd162017-01-26 22:01:52304 service_impl_->ListenForConnectionStateChange(connection);
imchenged10e962016-02-23 06:34:44305
306 // Trigger connection close. It should be propagated back up to
Derek Chengf8ffbec52017-12-06 19:43:04307 // |mock_controller_|.
mfoltz11fc4df82017-03-20 23:49:18308 PresentationInfo presentation_connection(presentation_url1_, kPresentationId);
imchengfafb67d02017-06-15 17:30:14309 PresentationConnectionStateChangeInfo closed_info(
mark a. foltze8ad3202018-04-23 22:50:23310 PresentationConnectionState::CLOSED);
mark a. foltzd9d2a4512018-04-16 20:42:45311 closed_info.close_reason = PresentationConnectionCloseReason::WENT_AWAY;
imchengfafb67d02017-06-15 17:30:14312 closed_info.message = "Foo";
imchenged10e962016-02-23 06:34:44313
mark a. foltz756d07e2018-07-20 20:59:18314 EXPECT_CALL(
315 mock_controller_,
316 OnConnectionClosed(InfoPtrEquals(presentation_connection),
317 PresentationConnectionCloseReason::WENT_AWAY, "Foo"));
imchengfafb67d02017-06-15 17:30:14318 state_changed_cb.Run(closed_info);
319 base::RunLoop().RunUntilIdle();
imchengf3e5a012015-11-20 04:08:37320}
321
mfoltzfcad52622016-09-03 03:08:33322TEST_F(PresentationServiceImplTest, SetSameDefaultPresentationUrls) {
Derek Cheng1071a232017-07-25 22:23:56323 EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrls(_, _)).Times(1);
mfoltz7a2c823b2016-10-08 01:35:24324 service_impl_->SetDefaultPresentationUrls(presentation_urls_);
imcheng271b9ef2015-03-18 19:43:19325 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
mfoltzfcad52622016-09-03 03:08:33326
327 // Same URLs as before; no-ops.
mfoltz7a2c823b2016-10-08 01:35:24328 service_impl_->SetDefaultPresentationUrls(presentation_urls_);
mfoltzfcad52622016-09-03 03:08:33329 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
imcheng271b9ef2015-03-18 19:43:19330}
331
mfoltz11fc4df82017-03-20 23:49:18332TEST_F(PresentationServiceImplTest, StartPresentationSuccess) {
btolsch8ca10fb22018-08-29 01:35:09333 PresentationConnectionCallback saved_success_cb;
mark a. foltz756d07e2018-07-20 20:59:18334 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, _))
btolsch8ca10fb22018-08-29 01:35:09335 .WillOnce([&saved_success_cb](const auto& request, auto success_cb,
336 auto error_cb) {
mark a. foltz756d07e2018-07-20 20:59:18337 saved_success_cb = std::move(success_cb);
338 });
imchengfafb67d02017-06-15 17:30:14339 service_impl_->StartPresentation(presentation_urls_,
mark a. foltzd9d2a4512018-04-16 20:42:45340 std::move(expect_presentation_success_cb_));
mark a. foltz756d07e2018-07-20 20:59:18341 EXPECT_FALSE(saved_success_cb.is_null());
imchengf3e5a012015-11-20 04:08:37342 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
343 .Times(1);
mark a. foltz756d07e2018-07-20 20:59:18344 std::move(saved_success_cb)
btolsch8ca10fb22018-08-29 01:35:09345 .Run(PresentationConnectionResult::New(
Wei4 Wange1c8c002023-04-24 23:30:25346 PresentationInfo::New(presentation_url1_, kPresentationId),
Mario Sanchez Prada2311a9e2019-08-26 14:29:49347 mojo::NullRemote(), mojo::NullReceiver()));
mark a. foltzd9d2a4512018-04-16 20:42:45348 ExpectPresentationCallbackWasRun();
imcheng271b9ef2015-03-18 19:43:19349}
350
mfoltz11fc4df82017-03-20 23:49:18351TEST_F(PresentationServiceImplTest, StartPresentationError) {
mark a. foltz756d07e2018-07-20 20:59:18352 base::OnceCallback<void(const PresentationError&)> saved_error_cb;
353 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, _))
354 .WillOnce([&](const auto& request, auto success_cb, auto error_cb) {
355 saved_error_cb = std::move(error_cb);
356 });
imchengfafb67d02017-06-15 17:30:14357 service_impl_->StartPresentation(presentation_urls_,
mark a. foltzd9d2a4512018-04-16 20:42:45358 std::move(expect_presentation_error_cb_));
mark a. foltz756d07e2018-07-20 20:59:18359 EXPECT_FALSE(saved_error_cb.is_null());
360 std::move(saved_error_cb)
361 .Run(PresentationError(PresentationErrorType::UNKNOWN, "Error message"));
mark a. foltzd9d2a4512018-04-16 20:42:45362 ExpectPresentationCallbackWasRun();
imchengfafb67d02017-06-15 17:30:14363}
364
365TEST_F(PresentationServiceImplTest, StartPresentationInProgress) {
mark a. foltz756d07e2018-07-20 20:59:18366 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, _)).Times(1);
imchengfafb67d02017-06-15 17:30:14367 // Uninvoked callbacks must outlive |service_impl_| since they get invoked
368 // at |service_impl_|'s destruction.
Peter Kasting341e1fb2018-02-24 00:03:01369 service_impl_->StartPresentation(presentation_urls_, base::DoNothing());
imchengfafb67d02017-06-15 17:30:14370
371 // This request should fail immediately, since there is already a
372 // StartPresentation in progress.
imchengfafb67d02017-06-15 17:30:14373 service_impl_->StartPresentation(presentation_urls_,
mark a. foltzd9d2a4512018-04-16 20:42:45374 std::move(expect_presentation_error_cb_));
375 ExpectPresentationCallbackWasRun();
imcheng271b9ef2015-03-18 19:43:19376}
377
mfoltz11fc4df82017-03-20 23:49:18378TEST_F(PresentationServiceImplTest, ReconnectPresentationSuccess) {
btolsch8ca10fb22018-08-29 01:35:09379 PresentationConnectionCallback saved_success_cb;
mark a. foltz756d07e2018-07-20 20:59:18380 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, kPresentationId, _, _))
btolsch8ca10fb22018-08-29 01:35:09381 .WillOnce([&saved_success_cb](const auto& request, const auto& id,
382 auto success_cb, auto error_cb) {
383 saved_success_cb = std::move(success_cb);
384 });
mark a. foltzd9d2a4512018-04-16 20:42:45385 service_impl_->ReconnectPresentation(
386 presentation_urls_, kPresentationId,
387 std::move(expect_presentation_success_cb_));
mark a. foltz756d07e2018-07-20 20:59:18388 EXPECT_FALSE(saved_success_cb.is_null());
imchengf3e5a012015-11-20 04:08:37389 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
390 .Times(1);
mark a. foltz756d07e2018-07-20 20:59:18391 std::move(saved_success_cb)
btolsch8ca10fb22018-08-29 01:35:09392 .Run(PresentationConnectionResult::New(
Wei4 Wange1c8c002023-04-24 23:30:25393 PresentationInfo::New(presentation_url1_, 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) {
Peter Kasting4524c8392023-10-17 15:55:08413 static constexpr char kPresentationUrlTemplate[] = "http://fooUrl%d";
414 static constexpr char kPresentationIdTemplate[] = "presentationId%d";
imchengfafb67d02017-06-15 17:30:14415 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) {
Peter Kasting4524c8392023-10-17 15:55:08420 std::vector<GURL> urls = {
421 GURL(base::StringPrintf(kPresentationUrlTemplate, i))};
imchengfafb67d02017-06-15 17:30:14422 // Uninvoked callbacks must outlive |service_impl_| since they get invoked
423 // at |service_impl_|'s destruction.
Peter Kasting341e1fb2018-02-24 00:03:01424 service_impl_->ReconnectPresentation(
Peter Kasting4524c8392023-10-17 15:55:08425 urls, base::StringPrintf(kPresentationIdTemplate, i),
426 base::DoNothing());
imchengfafb67d02017-06-15 17:30:14427 }
428
Peter Kasting4524c8392023-10-17 15:55:08429 std::vector<GURL> urls = {
430 GURL(base::StringPrintf(kPresentationUrlTemplate, i))};
imchengfafb67d02017-06-15 17:30:14431 // Exceeded maximum queue size, should invoke mojo callback with error.
imchengfafb67d02017-06-15 17:30:14432 service_impl_->ReconnectPresentation(
Peter Kasting4524c8392023-10-17 15:55:08433 urls, base::StringPrintf(kPresentationIdTemplate, i),
mark a. foltzd9d2a4512018-04-16 20:42:45434 std::move(expect_presentation_error_cb_));
435 ExpectPresentationCallbackWasRun();
imcheng271b9ef2015-03-18 19:43:19436}
437
mfoltzd0c3de12015-12-12 04:43:08438TEST_F(PresentationServiceImplTest, CloseConnection) {
imchengfafb67d02017-06-15 17:30:14439 EXPECT_CALL(mock_delegate_, CloseConnection(_, _, Eq(kPresentationId)));
440 service_impl_->CloseConnection(presentation_url1_, kPresentationId);
haibinlu4ba40192015-06-23 21:43:09441}
442
mfoltzd0c3de12015-12-12 04:43:08443TEST_F(PresentationServiceImplTest, Terminate) {
imchengfafb67d02017-06-15 17:30:14444 EXPECT_CALL(mock_delegate_, Terminate(_, _, Eq(kPresentationId)));
445 service_impl_->Terminate(presentation_url1_, kPresentationId);
mlamouric65a70d72015-11-27 16:28:59446}
447
zhaobinf3704f82017-01-12 07:19:36448TEST_F(PresentationServiceImplTest, ReceiverPresentationServiceDelegate) {
zhaobindca98f632017-06-29 18:42:28449 EXPECT_CALL(mock_receiver_delegate_, AddObserver(_, _, _)).Times(1);
zhaobinf3704f82017-01-12 07:19:36450
imchengfafb67d02017-06-15 17:30:14451 PresentationServiceImpl service_impl(main_rfh(), contents(), nullptr,
zhaobindca98f632017-06-29 18:42:28452 &mock_receiver_delegate_);
zhaobinf3704f82017-01-12 07:19:36453
454 ReceiverConnectionAvailableCallback callback;
zhaobindca98f632017-06-29 18:42:28455 EXPECT_CALL(mock_receiver_delegate_,
zhaobinf3704f82017-01-12 07:19:36456 RegisterReceiverConnectionAvailableCallback(_))
457 .WillOnce(SaveArg<0>(&callback));
458
Derek Cheng4de47c52017-10-10 01:05:54459 MockPresentationReceiver mock_receiver;
Mario Sanchez Prada23a91b22019-08-26 14:45:33460 mojo::Receiver<blink::mojom::PresentationReceiver>
461 presentation_receiver_receiver(&mock_receiver);
462 service_impl.SetReceiver(
463 presentation_receiver_receiver.BindNewPipeAndPassRemote());
zhaobinf3704f82017-01-12 07:19:36464 EXPECT_FALSE(callback.is_null());
465
mark a. foltze2084383c2018-05-11 19:21:50466 PresentationInfo expected(presentation_url1_, kPresentationId);
zhaobinf3704f82017-01-12 07:19:36467
imchengfafb67d02017-06-15 17:30:14468 // Client gets notified of receiver connections.
Mario Sanchez Prada2311a9e2019-08-26 14:29:49469 mojo::PendingRemote<PresentationConnection> controller_connection;
imchengfafb67d02017-06-15 17:30:14470 MockPresentationConnection mock_presentation_connection;
Mario Sanchez Prada2311a9e2019-08-26 14:29:49471 mojo::Receiver<PresentationConnection> connection_binding(
472 &mock_presentation_connection,
473 controller_connection.InitWithNewPipeAndPassReceiver());
474 mojo::Remote<PresentationConnection> receiver_connection;
Derek Cheng4de47c52017-10-10 01:05:54475
Wei4 Wange1c8c002023-04-24 23:30:25476 EXPECT_CALL(mock_receiver, OnReceiverConnectionAvailable(_)).Times(1);
477 callback.Run(PresentationConnectionResult::New(
478 PresentationInfo::New(expected), std::move(controller_connection),
479 receiver_connection.BindNewPipeAndPassReceiver()));
imchengfafb67d02017-06-15 17:30:14480 base::RunLoop().RunUntilIdle();
481
zhaobindca98f632017-06-29 18:42:28482 EXPECT_CALL(mock_receiver_delegate_, RemoveObserver(_, _)).Times(1);
483}
484
485TEST_F(PresentationServiceImplTest, ReceiverDelegateOnSubFrame) {
486 EXPECT_CALL(mock_receiver_delegate_, AddObserver(_, _, _)).Times(1);
487
488 PresentationServiceImpl service_impl(main_rfh(), contents(), nullptr,
489 &mock_receiver_delegate_);
Claudio DeSouzaee45cae2021-11-24 20:30:27490 service_impl.is_outermost_document_ = false;
zhaobindca98f632017-06-29 18:42:28491
492 ReceiverConnectionAvailableCallback callback;
493 EXPECT_CALL(mock_receiver_delegate_,
494 RegisterReceiverConnectionAvailableCallback(_))
495 .Times(0);
496
Mario Sanchez Prada2ae29e5a2019-08-26 14:42:23497 mojo::PendingRemote<PresentationController> presentation_controller_remote;
498 controller_receiver_.emplace(
499 &mock_controller_,
500 presentation_controller_remote.InitWithNewPipeAndPassReceiver());
zhaobindca98f632017-06-29 18:42:28501 service_impl.controller_delegate_ = nullptr;
Mario Sanchez Prada2ae29e5a2019-08-26 14:42:23502 service_impl.SetController(std::move(presentation_controller_remote));
zhaobindca98f632017-06-29 18:42:28503
504 EXPECT_CALL(mock_receiver_delegate_, Reset(_, _)).Times(0);
505 service_impl.Reset();
506
507 EXPECT_CALL(mock_receiver_delegate_, RemoveObserver(_, _)).Times(1);
mlamouri0c8ce522015-10-02 21:47:38508}
509
imcheng9f515d02015-02-10 20:09:24510} // namespace content