[M73 Dev][EFL] Disable VizDisplayCompositor for EFL port
[platform/framework/web/chromium-efl.git] / components / cast_channel / cast_message_handler.h
1 // Copyright 2018 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.
4
5 #ifndef COMPONENTS_CAST_CHANNEL_CAST_MESSAGE_HANDLER_H_
6 #define COMPONENTS_CAST_CHANNEL_CAST_MESSAGE_HANDLER_H_
7
8 #include "base/callback_list.h"
9 #include "base/containers/flat_map.h"
10 #include "base/containers/flat_set.h"
11 #include "base/gtest_prod_util.h"
12 #include "base/macros.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/sequence_checker.h"
15 #include "base/time/tick_clock.h"
16 #include "base/token.h"
17 #include "base/values.h"
18 #include "components/cast_channel/cast_message_util.h"
19 #include "components/cast_channel/cast_socket.h"
20
21 namespace service_manager {
22 class Connector;
23 }
24
25 namespace cast_channel {
26
27 class CastSocketService;
28
29 template <typename CallbackType>
30 struct PendingRequest {
31  public:
32   PendingRequest(int request_id,
33                  CallbackType callback,
34                  const base::TickClock* clock)
35       : request_id(request_id),
36         callback(std::move(callback)),
37         timeout_timer(clock) {}
38
39   virtual ~PendingRequest() = default;
40
41   int request_id;
42   CallbackType callback;
43   base::OneShotTimer timeout_timer;
44 };
45
46 // |app_id|: ID of app the result is for.
47 // |result|: Availability result from the receiver.
48 using GetAppAvailabilityCallback =
49     base::OnceCallback<void(const std::string& app_id,
50                             GetAppAvailabilityResult result)>;
51
52 // Represents an app availability request to a Cast sink.
53 struct GetAppAvailabilityRequest
54     : public PendingRequest<GetAppAvailabilityCallback> {
55  public:
56   GetAppAvailabilityRequest(int request_id,
57                             GetAppAvailabilityCallback callback,
58                             const base::TickClock* clock,
59                             const std::string& app_id);
60   ~GetAppAvailabilityRequest() override;
61
62   // App ID of the request.
63   std::string app_id;
64 };
65
66 // Represents an app launch request to a Cast sink.
67 using LaunchSessionCallback =
68     base::OnceCallback<void(LaunchSessionResponse response)>;
69 using LaunchSessionRequest = PendingRequest<LaunchSessionCallback>;
70
71 enum class Result { kOk, kFailed };
72 using ResultCallback = base::OnceCallback<void(Result result)>;
73
74 // Represents an app stop request to a Cast sink.
75 using StopSessionRequest = PendingRequest<ResultCallback>;
76
77 // Reresents request for a sink to set its volume level.
78 using SetVolumeRequest = PendingRequest<ResultCallback>;
79
80 // Represents a virtual connection on a cast channel. A virtual connection is
81 // given by a source and destination ID pair, and must be created before
82 // messages can be sent. Virtual connections are managed by CastMessageHandler.
83 struct VirtualConnection {
84   VirtualConnection(int channel_id,
85                     const std::string& source_id,
86                     const std::string& destination_id);
87   ~VirtualConnection();
88
89   bool operator<(const VirtualConnection& other) const;
90
91   // ID of cast channel.
92   int channel_id;
93
94   // Source ID (e.g. sender-0).
95   std::string source_id;
96
97   // Destination ID (e.g. receiver-0).
98   std::string destination_id;
99 };
100
101 struct InternalMessage {
102   InternalMessage(CastMessageType type, base::Value message);
103   ~InternalMessage();
104
105   CastMessageType type;
106   base::Value message;
107 };
108
109 // Default timeout amount for requests waiting for a response.
110 constexpr base::TimeDelta kRequestTimeout = base::TimeDelta::FromSeconds(5);
111
112 // Handles messages that are sent between this browser instance and the Cast
113 // devices connected to it. This class also manages virtual connections (VCs)
114 // with each connected Cast device and ensures a proper VC exists before the
115 // message is sent. This makes the concept of VC transparent to the client.
116 // This class may be created on any sequence, but other methods (including
117 // destructor) must be run on the same sequence that CastSocketService runs on.
118 class CastMessageHandler : public CastSocket::Observer {
119  public:
120   class Observer {
121    public:
122     virtual ~Observer() = default;
123     virtual void OnAppMessage(int channel_id, const CastMessage& message) {}
124     virtual void OnInternalMessage(int channel_id,
125                                    const InternalMessage& message) {}
126   };
127
128   // |connector|: Connector to be used for data_decoder service. The connector
129   // must not be bound to any thread.
130   // |data_decoder_batch_id|: Batch ID used for data_decoder service.
131   CastMessageHandler(CastSocketService* socket_service,
132                      std::unique_ptr<service_manager::Connector> connector,
133                      const base::Token& data_decoder_batch_id,
134                      const std::string& user_agent,
135                      const std::string& browser_version,
136                      const std::string& locale);
137   ~CastMessageHandler() override;
138
139   // Ensures a virtual connection exists for (|source_id|, |destination_id|) on
140   // the device given by |channel_id|, sending a virtual connection request to
141   // the device if necessary. Although a virtual connection is automatically
142   // created when sending a message, a caller may decide to create it beforehand
143   // in order to receive messages sooner.
144   virtual void EnsureConnection(int channel_id,
145                                 const std::string& source_id,
146                                 const std::string& destination_id);
147
148   // Sends an app availability for |app_id| to the device given by |socket|.
149   // |callback| is always invoked asynchronously, and will be invoked when a
150   // response is received, or if the request timed out. No-ops if there is
151   // already a pending request with the same socket and app ID.
152   virtual void RequestAppAvailability(CastSocket* socket,
153                                       const std::string& app_id,
154                                       GetAppAvailabilityCallback callback);
155
156   // Sends a receiver status request to the socket given by |channel_id|.
157   virtual void RequestReceiverStatus(int channel_id);
158
159   // Sends a broadcast message containing |app_ids| and |request| to the socket
160   // given by |channel_id|.
161   virtual void SendBroadcastMessage(int channel_id,
162                                     const std::vector<std::string>& app_ids,
163                                     const BroadcastRequest& request);
164
165   // Requests a session launch for |app_id| on the device given by |channel_id|.
166   // |callback| will be invoked with the response or with a timed out result if
167   // no response comes back before |launch_timeout|.
168   virtual void LaunchSession(int channel_id,
169                              const std::string& app_id,
170                              base::TimeDelta launch_timeout,
171                              LaunchSessionCallback callback);
172
173   // Stops the session given by |session_id| on the device given by
174   // |channel_id|. |callback| will be invoked with the result of the stop
175   // request.
176   virtual void StopSession(int channel_id,
177                            const std::string& session_id,
178                            ResultCallback callback);
179
180   // Sends |message| to the device given by |channel_id|. The caller may use
181   // this method to forward app messages from the SDK client to the device. It
182   // is invalid to call this method with a message in one of the Cast internal
183   // message namespaces.
184   virtual Result SendAppMessage(int channel_id, const CastMessage& message);
185
186   // Sends a media command |body|. Returns the ID of the request that is sent to
187   // the receiver. It is invalid to call this with a message body that is not a
188   // media command.  Returns |base::nullopt| if |channel_id| is invalid.
189   //
190   // Note: This API is designed to return a request ID instead of taking a
191   // callback. This is because a MEDIA_STATUS message from the receiver can be
192   // the response to a media command from a client. Thus when we get a
193   // MEDIA_STATUS message, we need to be able to (1) broadcast the message to
194   // all clients and (2) make sure the client that sent the media command
195   // receives the message only once *and* in the form of a response (by setting
196   // the sequenceNumber on the message).
197   virtual base::Optional<int> SendMediaRequest(
198       int channel_id,
199       const base::Value& body,
200       const std::string& source_id,
201       const std::string& destination_id);
202
203   // Sends a set system volume command |body|. |callback| will be invoked
204   // with the result of the operation. It is invalid to call this with
205   // a message body that is not a volume request.
206   virtual Result SendSetVolumeRequest(int channel_id,
207                                       const base::Value& body,
208                                       const std::string& source_id,
209                                       ResultCallback callback);
210
211   void AddObserver(Observer* observer);
212   void RemoveObserver(Observer* observer);
213
214   // CastSocket::Observer implementation.
215   void OnError(const CastSocket& socket, ChannelError error_state) override;
216   void OnMessage(const CastSocket& socket, const CastMessage& message) override;
217   void OnReadyStateChanged(const CastSocket& socket) override;
218
219   const std::string& sender_id() const { return sender_id_; }
220
221  private:
222   friend class CastMessageHandlerTest;
223   FRIEND_TEST_ALL_PREFIXES(CastMessageHandlerTest, HandlePendingRequest);
224
225   // Set of PendingRequests for a CastSocket.
226   class PendingRequests {
227    public:
228     PendingRequests();
229     ~PendingRequests();
230
231     // Returns true if this is the first request for the given app ID.
232     bool AddAppAvailabilityRequest(
233         std::unique_ptr<GetAppAvailabilityRequest> request);
234
235     bool AddLaunchRequest(std::unique_ptr<LaunchSessionRequest> request,
236                           base::TimeDelta timeout);
237     bool AddStopRequest(std::unique_ptr<StopSessionRequest> request);
238     void AddVolumeRequest(std::unique_ptr<SetVolumeRequest> request);
239     void HandlePendingRequest(int request_id, const base::Value& response);
240
241    private:
242     // Invokes the pending callback associated with |request_id| with a timed
243     // out result.
244     void AppAvailabilityTimedOut(int request_id);
245     void LaunchSessionTimedOut(int request_id);
246     void StopSessionTimedOut(int request_id);
247     void SetVolumeTimedOut(int request_id);
248
249     // Requests are kept in the order in which they were created.
250     std::vector<std::unique_ptr<GetAppAvailabilityRequest>>
251         pending_app_availability_requests_;
252     std::unique_ptr<LaunchSessionRequest> pending_launch_session_request_;
253     std::unique_ptr<StopSessionRequest> pending_stop_session_request_;
254     base::flat_map<int, std::unique_ptr<SetVolumeRequest>>
255         pending_volume_requests_by_id_;
256   };
257
258   // Used internally to generate the next ID to use in a request type message.
259   // Returns a positive integer (unless the counter overflows).
260   int NextRequestId() { return ++next_request_id_; }
261
262   PendingRequests* GetOrCreatePendingRequests(int channel_id);
263
264   // Sends |message| over |socket|. This also ensures the necessary virtual
265   // connection exists before sending the message.
266   void SendCastMessage(CastSocket* socket, const CastMessage& message);
267
268   // Sends a virtual connection request to |socket| if the virtual connection
269   // for (|source_id|, |destination_id|) does not yet exist.
270   void DoEnsureConnection(CastSocket* socket,
271                           const std::string& source_id,
272                           const std::string& destination_id);
273
274   // Callback for CastTransport::SendMessage.
275   void OnMessageSent(int result);
276
277   void HandleCastInternalMessage(int channel_id,
278                                  const std::string& source_id,
279                                  const std::string& destination_id,
280                                  std::unique_ptr<base::Value> payload);
281
282   // Set of pending requests keyed by socket ID.
283   base::flat_map<int, std::unique_ptr<PendingRequests>> pending_requests_;
284
285   // Source ID used for platform messages. The suffix is randomized to
286   // distinguish it from other Cast senders on the same network.
287   const std::string sender_id_;
288
289   // Used for parsing JSON payload from receivers.
290   std::unique_ptr<service_manager::Connector> connector_;
291   const base::Token data_decoder_batch_id_;
292
293   // User agent and browser version strings included in virtual connection
294   // messages.
295   const std::string user_agent_;
296   const std::string browser_version_;
297
298   // Locale string used for session launch requests.
299   const std::string locale_;
300
301   int next_request_id_ = 0;
302
303   base::ObserverList<Observer>::Unchecked observers_;
304
305   // Set of virtual connections opened to receivers.
306   base::flat_set<VirtualConnection> virtual_connections_;
307
308   CastSocketService* const socket_service_;
309
310   // Non-owned pointer to TickClock used for request timeouts.
311   const base::TickClock* const clock_;
312
313   SEQUENCE_CHECKER(sequence_checker_);
314   base::WeakPtrFactory<CastMessageHandler> weak_ptr_factory_;
315
316   DISALLOW_COPY_AND_ASSIGN(CastMessageHandler);
317 };
318
319 }  // namespace cast_channel
320
321 #endif  // COMPONENTS_CAST_CHANNEL_CAST_MESSAGE_HANDLER_H_