1 // Copyright 2020 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 CAST_SENDER_CAST_PLATFORM_CLIENT_H_
6 #define CAST_SENDER_CAST_PLATFORM_CLIENT_H_
7 
8 #include <functional>
9 #include <map>
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "absl/types/optional.h"
15 #include "cast/common/channel/cast_message_handler.h"
16 #include "cast/sender/channel/message_util.h"
17 #include "util/alarm.h"
18 #include "util/json/json_value.h"
19 
20 namespace openscreen {
21 namespace cast {
22 
23 struct ServiceInfo;
24 class VirtualConnectionRouter;
25 
26 // This class handles Cast messages that generally relate to the "platform", in
27 // other words not a specific app currently running (e.g. app availability,
28 // receiver status).  These messages follow a request/response format, so each
29 // request requires a corresponding response callback.  These requests will also
30 // timeout if there is no response after a certain amount of time (currently 5
31 // seconds).  The timeout callbacks will be called on the thread managed by
32 // |task_runner|.
33 class CastPlatformClient final : public CastMessageHandler {
34  public:
35   using AppAvailabilityCallback =
36       std::function<void(const std::string& app_id, AppAvailabilityResult)>;
37 
38   CastPlatformClient(VirtualConnectionRouter* router,
39                      ClockNowFunctionPtr clock,
40                      TaskRunner* task_runner);
41   ~CastPlatformClient() override;
42 
43   // Requests availability information for |app_id| from the receiver identified
44   // by |device_id|.  |callback| will be called exactly once with a result.
45   absl::optional<int> RequestAppAvailability(const std::string& device_id,
46                                              const std::string& app_id,
47                                              AppAvailabilityCallback callback);
48 
49   // Notifies this object about general receiver connectivity or property
50   // changes.
51   void AddOrUpdateReceiver(const ServiceInfo& device, int socket_id);
52   void RemoveReceiver(const ServiceInfo& device);
53 
54   void CancelRequest(int request_id);
55 
56  private:
57   struct AvailabilityRequest {
58     int request_id;
59     std::string app_id;
60     std::unique_ptr<Alarm> timeout;
61     AppAvailabilityCallback callback;
62   };
63 
64   struct PendingRequests {
65     std::vector<AvailabilityRequest> availability;
66   };
67 
68   // CastMessageHandler overrides.
69   void OnMessage(VirtualConnectionRouter* router,
70                  CastSocket* socket,
71                  ::cast::channel::CastMessage message) override;
72 
73   void HandleResponse(const std::string& device_id,
74                       int request_id,
75                       const Json::Value& message);
76 
77   void CancelAppAvailabilityRequest(int request_id);
78 
79   static int GetNextRequestId();
80 
81   static int next_request_id_;
82 
83   const std::string sender_id_;
84   VirtualConnectionRouter* const virtual_conn_router_;
85   std::map<std::string /* device_id */, int> socket_id_by_device_id_;
86   std::map<std::string /* device_id */, PendingRequests>
87       pending_requests_by_device_id_;
88 
89   const ClockNowFunctionPtr clock_;
90   TaskRunner* const task_runner_;
91 };
92 
93 }  // namespace cast
94 }  // namespace openscreen
95 
96 #endif  // CAST_SENDER_CAST_PLATFORM_CLIENT_H_
97