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 "content/renderer/presentation/presentation_dispatcher.h"
7 #include "base/logging.h"
8 #include "content/common/presentation/presentation_service.mojom.h"
9 #include "content/public/common/service_registry.h"
10 #include "content/public/renderer/render_frame.h"
11 #include "content/renderer/presentation/presentation_session_client.h"
12 #include "third_party/WebKit/public/platform/WebString.h"
13 #include "third_party/WebKit/public/platform/modules/presentation/WebPresentationController.h"
14 #include "third_party/WebKit/public/platform/modules/presentation/WebPresentationError.h"
18 blink::WebPresentationError::ErrorType
GetWebPresentationErrorTypeFromMojo(
19 presentation::PresentationErrorType mojoErrorType
) {
20 switch (mojoErrorType
) {
21 case presentation::PRESENTATION_ERROR_TYPE_NO_AVAILABLE_SCREENS
:
22 return blink::WebPresentationError::ErrorTypeNoAvailableScreens
;
23 case presentation::PRESENTATION_ERROR_TYPE_SESSION_REQUEST_CANCELLED
:
24 return blink::WebPresentationError::ErrorTypeSessionRequestCancelled
;
25 case presentation::PRESENTATION_ERROR_TYPE_NO_PRESENTATION_FOUND
:
26 return blink::WebPresentationError::ErrorTypeNoPresentationFound
;
27 case presentation::PRESENTATION_ERROR_TYPE_UNKNOWN
:
29 return blink::WebPresentationError::ErrorTypeUnknown
;
37 PresentationDispatcher::PresentationDispatcher(RenderFrame
* render_frame
)
38 : RenderFrameObserver(render_frame
),
39 controller_(nullptr) {
42 PresentationDispatcher::~PresentationDispatcher() {
43 // Controller should be destroyed before the dispatcher when frame is
48 void PresentationDispatcher::setController(
49 blink::WebPresentationController
* controller
) {
50 // There shouldn't be any swapping from one non-null controller to another.
51 DCHECK(controller
!= controller_
&& (!controller
|| !controller_
));
52 controller_
= controller
;
53 // The controller is set to null when the frame is about to be detached.
54 // Nothing is listening for screen availability anymore but the Mojo service
55 // will know about the frame being detached anyway.
58 void PresentationDispatcher::updateAvailableChangeWatched(bool watched
) {
59 ConnectToPresentationServiceIfNeeded();
61 presentation_service_
->GetScreenAvailability(
63 base::Bind(&PresentationDispatcher::OnScreenAvailabilityChanged
,
64 base::Unretained(this)));
66 presentation_service_
->OnScreenAvailabilityListenerRemoved();
70 void PresentationDispatcher::startSession(
71 const blink::WebString
& presentationUrl
,
72 const blink::WebString
& presentationId
,
73 blink::WebPresentationSessionClientCallbacks
* callback
) {
75 ConnectToPresentationServiceIfNeeded();
77 // The dispatcher owns the service so |this| will be valid when
78 // OnSessionCreated() is called. |callback| needs to be alive and also needs
79 // to be destroyed so we transfer its ownership to the mojo callback.
80 presentation_service_
->StartSession(
81 presentationUrl
.utf8(),
82 presentationId
.utf8(),
83 base::Bind(&PresentationDispatcher::OnSessionCreated
,
84 base::Unretained(this),
85 base::Owned(callback
)));
88 void PresentationDispatcher::joinSession(
89 const blink::WebString
& presentationUrl
,
90 const blink::WebString
& presentationId
,
91 blink::WebPresentationSessionClientCallbacks
* callback
) {
93 ConnectToPresentationServiceIfNeeded();
95 // The dispatcher owns the service so |this| will be valid when
96 // OnSessionCreated() is called. |callback| needs to be alive and also needs
97 // to be destroyed so we transfer its ownership to the mojo callback.
98 presentation_service_
->JoinSession(
99 presentationUrl
.utf8(),
100 presentationId
.utf8(),
101 base::Bind(&PresentationDispatcher::OnSessionCreated
,
102 base::Unretained(this),
103 base::Owned(callback
)));
106 void PresentationDispatcher::OnScreenAvailabilityChanged(bool available
) {
110 // Reset the callback to get the next event.
111 updateAvailableChangeWatched(controller_
->isAvailableChangeWatched());
113 controller_
->didChangeAvailability(available
);
116 void PresentationDispatcher::OnDefaultSessionStarted(
117 presentation::PresentationSessionInfoPtr session_info
) {
121 // Reset the callback to get the next event.
122 presentation_service_
->ListenForDefaultSessionStart(base::Bind(
123 &PresentationDispatcher::OnDefaultSessionStarted
,
124 base::Unretained(this)));
126 DCHECK(!session_info
.is_null());
127 PresentationSessionDispatcher
* session_dispatcher
=
128 new PresentationSessionDispatcher(session_info
.Pass());
129 presentation_session_dispatchers_
.push_back(session_dispatcher
);
130 controller_
->didStartDefaultSession(
131 new PresentationSessionClient(session_dispatcher
));
134 void PresentationDispatcher::OnSessionCreated(
135 blink::WebPresentationSessionClientCallbacks
* callback
,
136 presentation::PresentationSessionInfoPtr session_info
,
137 presentation::PresentationErrorPtr error
) {
139 if (!error
.is_null()) {
140 DCHECK(session_info
.is_null());
141 callback
->onError(new blink::WebPresentationError(
142 GetWebPresentationErrorTypeFromMojo(error
->errorType
),
143 blink::WebString::fromUTF8(error
->message
)));
147 DCHECK(!session_info
.is_null());
148 PresentationSessionDispatcher
* session_dispatcher
=
149 new PresentationSessionDispatcher(session_info
.Pass());
150 presentation_session_dispatchers_
.push_back(session_dispatcher
);
151 callback
->onSuccess(new PresentationSessionClient(session_dispatcher
));
154 void PresentationDispatcher::ConnectToPresentationServiceIfNeeded() {
155 if (presentation_service_
.get())
158 render_frame()->GetServiceRegistry()->ConnectToRemoteService(
159 &presentation_service_
);
160 presentation_service_
->ListenForDefaultSessionStart(base::Bind(
161 &PresentationDispatcher::OnDefaultSessionStarted
,
162 base::Unretained(this)));
165 } // namespace content