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