[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / presentation / presentation_service_impl.h
blob0a3fe6fbab3f5787ee3aa291ae20a9dc337d3e25
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 #ifndef CONTENT_BROWSER_PRESENTATION_PRESENTATION_SERVICE_IMPL_H_
6 #define CONTENT_BROWSER_PRESENTATION_PRESENTATION_SERVICE_IMPL_H_
8 #include <deque>
9 #include <map>
10 #include <string>
12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "base/containers/hash_tables.h"
15 #include "base/containers/scoped_ptr_map.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/macros.h"
18 #include "base/memory/linked_ptr.h"
19 #include "base/memory/scoped_ptr.h"
20 #include "base/memory/scoped_vector.h"
21 #include "base/memory/weak_ptr.h"
22 #include "content/common/content_export.h"
23 #include "content/common/presentation/presentation_service.mojom.h"
24 #include "content/public/browser/navigation_details.h"
25 #include "content/public/browser/presentation_screen_availability_listener.h"
26 #include "content/public/browser/presentation_service_delegate.h"
27 #include "content/public/browser/web_contents_observer.h"
28 #include "content/public/common/frame_navigate_params.h"
29 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
31 namespace content {
33 struct FrameNavigateParams;
34 struct LoadCommittedDetails;
35 struct PresentationSessionMessage;
36 class RenderFrameHost;
38 using NewSessionMojoCallback = mojo::Callback<
39 void(presentation::PresentationSessionInfoPtr,
40 presentation::PresentationErrorPtr)>;
42 // Implementation of Mojo PresentationService.
43 // It handles Presentation API requests coming from Blink / renderer process
44 // and delegates the requests to the embedder's media router via
45 // PresentationServiceDelegate.
46 // An instance of this class tied to a RenderFrameHost and listens to events
47 // related to the RFH via implementing WebContentsObserver.
48 // This class is instantiated on-demand via Mojo's ConnectToRemoteService
49 // from the renderer when the first presentation API request is handled.
50 class CONTENT_EXPORT PresentationServiceImpl
51 : public NON_EXPORTED_BASE(presentation::PresentationService),
52 public WebContentsObserver,
53 public PresentationServiceDelegate::Observer {
54 public:
55 ~PresentationServiceImpl() override;
57 // Static factory method to create an instance of PresentationServiceImpl.
58 // |render_frame_host|: The RFH the instance is associated with.
59 // |request|: The instance will be bound to this request. Used for Mojo setup.
60 static void CreateMojoService(
61 RenderFrameHost* render_frame_host,
62 mojo::InterfaceRequest<presentation::PresentationService> request);
64 private:
65 friend class PresentationServiceImplTest;
66 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest, Reset);
67 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest, DidNavigateThisFrame);
68 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
69 DidNavigateOtherFrame);
70 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest, ThisRenderFrameDeleted);
71 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
72 OtherRenderFrameDeleted);
73 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest, DelegateFails);
74 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
75 SetDefaultPresentationUrl);
76 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
77 SetSameDefaultPresentationUrl);
78 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
79 ClearDefaultPresentationUrl);
80 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
81 ListenForDefaultSessionStart);
82 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
83 ListenForDefaultSessionStartAfterSet);
84 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
85 DefaultSessionStartReset);
86 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
87 ReceiveSessionMessagesAfterReset);
88 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
89 MaxPendingStartSessionRequests);
90 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
91 MaxPendingJoinSessionRequests);
92 FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
93 ListenForSessionStateChange);
94 // Maximum number of pending JoinSession requests at any given time.
95 static const int kMaxNumQueuedSessionRequests = 10;
97 using DefaultSessionMojoCallback =
98 mojo::Callback<void(presentation::PresentationSessionInfoPtr)>;
99 using SessionStateCallback =
100 mojo::Callback<void(presentation::PresentationSessionInfoPtr,
101 presentation::PresentationSessionState)>;
102 using SessionMessagesCallback =
103 mojo::Callback<void(mojo::Array<presentation::SessionMessagePtr>)>;
104 using SendMessageMojoCallback = mojo::Callback<void(bool)>;
106 // Listener implementation owned by PresentationServiceImpl. An instance of
107 // this is created when PresentationRequest.getAvailability() is resolved.
108 // The instance receives screen availability results from the embedder and
109 // propagates results back to PresentationServiceImpl.
110 class CONTENT_EXPORT ScreenAvailabilityListenerImpl
111 : public PresentationScreenAvailabilityListener {
112 public:
113 ScreenAvailabilityListenerImpl(
114 const std::string& availability_url,
115 PresentationServiceImpl* service);
116 ~ScreenAvailabilityListenerImpl() override;
118 // PresentationScreenAvailabilityListener implementation.
119 std::string GetAvailabilityUrl() const override;
120 void OnScreenAvailabilityChanged(bool available) override;
122 private:
123 const std::string availability_url_;
124 PresentationServiceImpl* const service_;
127 class CONTENT_EXPORT DefaultSessionStartContext {
128 public:
129 DefaultSessionStartContext();
130 ~DefaultSessionStartContext();
132 // Adds a callback. May invoke the callback immediately if |session| using
133 // default presentation URL was already started.
134 void AddCallback(const DefaultSessionMojoCallback& callback);
136 // Sets the session info. Maybe invoke callbacks queued with AddCallback().
137 void set_session(const PresentationSessionInfo& session);
139 private:
140 // Flush all queued callbacks by invoking them with null
141 // PresentationSessionInfoPtr.
142 void Reset();
144 ScopedVector<DefaultSessionMojoCallback> callbacks_;
145 scoped_ptr<PresentationSessionInfo> session_;
148 // Ensures the provided NewSessionMojoCallback is invoked exactly once
149 // before it goes out of scope.
150 class NewSessionMojoCallbackWrapper {
151 public:
152 explicit NewSessionMojoCallbackWrapper(
153 const NewSessionMojoCallback& callback);
154 ~NewSessionMojoCallbackWrapper();
156 void Run(presentation::PresentationSessionInfoPtr session,
157 presentation::PresentationErrorPtr error);
159 private:
160 NewSessionMojoCallback callback_;
162 DISALLOW_COPY_AND_ASSIGN(NewSessionMojoCallbackWrapper);
165 // |render_frame_host|: The RFH this instance is associated with.
166 // |web_contents|: The WebContents to observe.
167 // |delegate|: Where Presentation API requests are delegated to. Not owned
168 // by this class.
169 PresentationServiceImpl(
170 RenderFrameHost* render_frame_host,
171 WebContents* web_contents,
172 PresentationServiceDelegate* delegate);
174 // PresentationService implementation.
175 void SetDefaultPresentationURL(const mojo::String& url) override;
176 void SetClient(presentation::PresentationServiceClientPtr client) override;
177 void ListenForScreenAvailability(const mojo::String& url) override;
178 void StopListeningForScreenAvailability(const mojo::String& url) override;
179 void ListenForDefaultSessionStart(
180 const DefaultSessionMojoCallback& callback) override;
181 void StartSession(
182 const mojo::String& presentation_url,
183 const NewSessionMojoCallback& callback) override;
184 void JoinSession(
185 const mojo::String& presentation_url,
186 const mojo::String& presentation_id,
187 const NewSessionMojoCallback& callback) override;
188 void SendSessionMessage(presentation::PresentationSessionInfoPtr session_info,
189 presentation::SessionMessagePtr session_message,
190 const SendMessageMojoCallback& callback) override;
191 void CloseSession(
192 const mojo::String& presentation_url,
193 const mojo::String& presentation_id) override;
194 void ListenForSessionStateChange() override;
195 void ListenForSessionMessages(
196 presentation::PresentationSessionInfoPtr session) override;
198 // Creates a binding between this object and |request|.
199 void Bind(mojo::InterfaceRequest<presentation::PresentationService> request);
201 // WebContentsObserver override.
202 void DidNavigateAnyFrame(
203 content::RenderFrameHost* render_frame_host,
204 const content::LoadCommittedDetails& details,
205 const content::FrameNavigateParams& params) override;
206 void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
208 // PresentationServiceDelegate::Observer
209 void OnDelegateDestroyed() override;
210 void OnDefaultPresentationStarted(const PresentationSessionInfo& session)
211 override;
213 // Finds the callback from |pending_join_session_cbs_| using
214 // |request_session_id|.
215 // If it exists, invoke it with |session| and |error|, then erase it from
216 // |pending_join_session_cbs_|.
217 void RunAndEraseJoinSessionMojoCallback(
218 int request_session_id,
219 presentation::PresentationSessionInfoPtr session,
220 presentation::PresentationErrorPtr error);
222 // Removes all listeners and resets default presentation URL on this instance
223 // and informs the PresentationServiceDelegate of such.
224 void Reset();
226 // These functions are bound as base::Callbacks and passed to
227 // embedder's implementation of PresentationServiceDelegate for later
228 // invocation.
229 void OnStartSessionSucceeded(
230 int request_session_id,
231 const PresentationSessionInfo& session_info);
232 void OnStartSessionError(
233 int request_session_id,
234 const PresentationError& error);
235 void OnJoinSessionSucceeded(
236 int request_session_id,
237 const PresentationSessionInfo& session_info);
238 void OnJoinSessionError(
239 int request_session_id,
240 const PresentationError& error);
241 void OnSendMessageCallback(bool sent);
243 // Passed to embedder's implementation of PresentationServiceDelegate for
244 // later invocation when session messages arrive.
245 void OnSessionMessages(
246 const content::PresentationSessionInfo& session,
247 const ScopedVector<PresentationSessionMessage>& messages,
248 bool pass_ownership);
250 // Associates a JoinSession |callback| with a unique request ID and
251 // stores it in a map.
252 // Returns a positive value on success.
253 int RegisterJoinSessionCallback(const NewSessionMojoCallback& callback);
255 // Invoked by the embedder's PresentationServiceDelegate when a
256 // presentation session's state has changed.
257 void OnSessionStateChanged(const PresentationSessionInfo& session_info,
258 PresentationSessionState session_state);
260 // Returns true if this object is associated with |render_frame_host|.
261 bool FrameMatches(content::RenderFrameHost* render_frame_host) const;
263 // Embedder-specific delegate to forward Presentation requests to.
264 // May be null if embedder does not support Presentation API.
265 PresentationServiceDelegate* delegate_;
267 // Proxy to the PresentationServiceClient to send results (e.g., screen
268 // availability) to.
269 presentation::PresentationServiceClientPtr client_;
271 std::string default_presentation_url_;
273 using ScreenAvailabilityListenerMap =
274 base::ScopedPtrMap<std::string, scoped_ptr<ScreenAvailabilityListenerImpl>>;
275 ScreenAvailabilityListenerMap screen_availability_listeners_;
277 // For StartSession requests.
278 // Set to a positive value when a StartSession request is being processed.
279 int start_session_request_id_;
280 scoped_ptr<NewSessionMojoCallbackWrapper> pending_start_session_cb_;
282 // For JoinSession requests.
283 base::hash_map<int, linked_ptr<NewSessionMojoCallbackWrapper>>
284 pending_join_session_cbs_;
286 scoped_ptr<DefaultSessionStartContext> default_session_start_context_;
288 // RAII binding of |this| to an Presentation interface request.
289 // The binding is removed when binding_ is cleared or goes out of scope.
290 scoped_ptr<mojo::Binding<presentation::PresentationService>> binding_;
292 // There can be only one send message request at a time.
293 scoped_ptr<SendMessageMojoCallback> send_message_callback_;
295 scoped_ptr<SessionMessagesCallback> on_session_messages_callback_;
297 // ID of the RenderFrameHost this object is associated with.
298 int render_process_id_;
299 int render_frame_id_;
301 // NOTE: Weak pointers must be invalidated before all other member variables.
302 base::WeakPtrFactory<PresentationServiceImpl> weak_factory_;
304 DISALLOW_COPY_AND_ASSIGN(PresentationServiceImpl);
307 } // namespace content
309 #endif // CONTENT_BROWSER_PRESENTATION_PRESENTATION_SERVICE_IMPL_H_