[Presentation API] Plumbing of |onstatechange| from the Mojo service to the public...
[chromium-blink-merge.git] / content / renderer / presentation / presentation_dispatcher.cc
blob7bbca6bf032d976a8c844996ee61bbe23e32238f
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"
15 #include "third_party/WebKit/public/web/WebDocument.h"
16 #include "third_party/WebKit/public/web/WebLocalFrame.h"
17 #include "url/gurl.h"
19 namespace {
21 blink::WebPresentationError::ErrorType GetWebPresentationErrorTypeFromMojo(
22 presentation::PresentationErrorType mojoErrorType) {
23 switch (mojoErrorType) {
24 case presentation::PRESENTATION_ERROR_TYPE_NO_AVAILABLE_SCREENS:
25 return blink::WebPresentationError::ErrorTypeNoAvailableScreens;
26 case presentation::PRESENTATION_ERROR_TYPE_SESSION_REQUEST_CANCELLED:
27 return blink::WebPresentationError::ErrorTypeSessionRequestCancelled;
28 case presentation::PRESENTATION_ERROR_TYPE_NO_PRESENTATION_FOUND:
29 return blink::WebPresentationError::ErrorTypeNoPresentationFound;
30 case presentation::PRESENTATION_ERROR_TYPE_UNKNOWN:
31 default:
32 return blink::WebPresentationError::ErrorTypeUnknown;
36 blink::WebPresentationSessionState GetWebPresentationSessionStateFromMojo(
37 presentation::PresentationSessionState mojoSessionState) {
38 switch (mojoSessionState) {
39 case presentation::PRESENTATION_SESSION_STATE_CONNECTED:
40 return blink::WebPresentationSessionState::Connected;
41 case presentation::PRESENTATION_SESSION_STATE_DISCONNECTED:
42 return blink::WebPresentationSessionState::Disconnected;
45 NOTREACHED();
46 return blink::WebPresentationSessionState::Disconnected;
49 GURL GetPresentationURLFromFrame(content::RenderFrame* frame) {
50 DCHECK(frame);
52 GURL url(frame->GetWebFrame()->document().defaultPresentationURL());
53 return url.is_valid() ? url : GURL();
56 } // namespace
58 namespace content {
60 PresentationDispatcher::PresentationDispatcher(RenderFrame* render_frame)
61 : RenderFrameObserver(render_frame),
62 controller_(nullptr) {
65 PresentationDispatcher::~PresentationDispatcher() {
66 // Controller should be destroyed before the dispatcher when frame is
67 // destroyed.
68 DCHECK(!controller_);
71 void PresentationDispatcher::setController(
72 blink::WebPresentationController* controller) {
73 // There shouldn't be any swapping from one non-null controller to another.
74 DCHECK(controller != controller_ && (!controller || !controller_));
75 controller_ = controller;
76 // The controller is set to null when the frame is about to be detached.
77 // Nothing is listening for screen availability anymore but the Mojo service
78 // will know about the frame being detached anyway.
81 void PresentationDispatcher::updateAvailableChangeWatched(bool watched) {
82 GURL presentation_url(GetPresentationURLFromFrame(render_frame()));
83 DoUpdateAvailableChangeWatched(presentation_url.spec(), watched);
86 void PresentationDispatcher::DoUpdateAvailableChangeWatched(
87 const std::string& presentation_url, bool watched) {
88 ConnectToPresentationServiceIfNeeded();
89 if (watched) {
90 presentation_service_->GetScreenAvailability(
91 presentation_url,
92 base::Bind(&PresentationDispatcher::OnScreenAvailabilityChanged,
93 base::Unretained(this)));
94 } else {
95 presentation_service_->OnScreenAvailabilityListenerRemoved(
96 presentation_url);
100 void PresentationDispatcher::startSession(
101 const blink::WebString& presentationUrl,
102 const blink::WebString& presentationId,
103 blink::WebPresentationSessionClientCallbacks* callback) {
104 DCHECK(callback);
105 ConnectToPresentationServiceIfNeeded();
107 // The dispatcher owns the service so |this| will be valid when
108 // OnSessionCreated() is called. |callback| needs to be alive and also needs
109 // to be destroyed so we transfer its ownership to the mojo callback.
110 presentation_service_->StartSession(
111 presentationUrl.utf8(),
112 presentationId.utf8(),
113 base::Bind(&PresentationDispatcher::OnSessionCreated,
114 base::Unretained(this),
115 base::Owned(callback)));
118 void PresentationDispatcher::joinSession(
119 const blink::WebString& presentationUrl,
120 const blink::WebString& presentationId,
121 blink::WebPresentationSessionClientCallbacks* callback) {
122 DCHECK(callback);
123 ConnectToPresentationServiceIfNeeded();
125 // The dispatcher owns the service so |this| will be valid when
126 // OnSessionCreated() is called. |callback| needs to be alive and also needs
127 // to be destroyed so we transfer its ownership to the mojo callback.
128 presentation_service_->JoinSession(
129 presentationUrl.utf8(),
130 presentationId.utf8(),
131 base::Bind(&PresentationDispatcher::OnSessionCreated,
132 base::Unretained(this),
133 base::Owned(callback)));
136 void PresentationDispatcher::closeSession(
137 const blink::WebString& presentationUrl,
138 const blink::WebString& presentationId) {
139 ConnectToPresentationServiceIfNeeded();
141 presentation_service_->CloseSession(
142 presentationUrl.utf8(),
143 presentationId.utf8());
146 void PresentationDispatcher::DidChangeDefaultPresentation() {
147 GURL presentation_url(GetPresentationURLFromFrame(render_frame()));
149 ConnectToPresentationServiceIfNeeded();
150 presentation_service_->SetDefaultPresentationURL(
151 presentation_url.spec(), mojo::String());
154 void PresentationDispatcher::OnScreenAvailabilityChanged(
155 const std::string& presentation_url, bool available) {
156 if (!controller_)
157 return;
159 // Reset the callback to get the next event.
160 DoUpdateAvailableChangeWatched(presentation_url,
161 controller_->isAvailableChangeWatched());
163 controller_->didChangeAvailability(available);
166 void PresentationDispatcher::OnDefaultSessionStarted(
167 presentation::PresentationSessionInfoPtr session_info) {
168 if (!controller_)
169 return;
171 // Reset the callback to get the next event.
172 presentation_service_->ListenForDefaultSessionStart(base::Bind(
173 &PresentationDispatcher::OnDefaultSessionStarted,
174 base::Unretained(this)));
176 DCHECK(!session_info.is_null());
177 controller_->didStartDefaultSession(
178 new PresentationSessionClient(session_info.Pass()));
181 void PresentationDispatcher::OnSessionCreated(
182 blink::WebPresentationSessionClientCallbacks* callback,
183 presentation::PresentationSessionInfoPtr session_info,
184 presentation::PresentationErrorPtr error) {
185 DCHECK(callback);
186 if (!error.is_null()) {
187 DCHECK(session_info.is_null());
188 callback->onError(new blink::WebPresentationError(
189 GetWebPresentationErrorTypeFromMojo(error->error_type),
190 blink::WebString::fromUTF8(error->message)));
191 return;
194 DCHECK(!session_info.is_null());
195 callback->onSuccess(new PresentationSessionClient(session_info.Pass()));
198 void PresentationDispatcher::OnSessionStateChange(
199 presentation::PresentationSessionInfoPtr session_info,
200 presentation::PresentationSessionState session_state) {
201 if (!controller_)
202 return;
204 presentation_service_->ListenForSessionStateChange(base::Bind(
205 &PresentationDispatcher::OnSessionStateChange,
206 base::Unretained(this)));
208 DCHECK(!session_info.is_null());
209 controller_->didChangeSessionState(
210 new PresentationSessionClient(session_info.Pass()),
211 GetWebPresentationSessionStateFromMojo(session_state));
214 void PresentationDispatcher::ConnectToPresentationServiceIfNeeded() {
215 if (presentation_service_.get())
216 return;
218 render_frame()->GetServiceRegistry()->ConnectToRemoteService(
219 &presentation_service_);
220 presentation_service_->ListenForDefaultSessionStart(base::Bind(
221 &PresentationDispatcher::OnDefaultSessionStarted,
222 base::Unretained(this)));
223 presentation_service_->ListenForSessionStateChange(base::Bind(
224 &PresentationDispatcher::OnSessionStateChange,
225 base::Unretained(this)));
228 } // namespace content