aboutsummaryrefslogtreecommitdiff
path: root/cast/sender/cast_platform_client.h
blob: 8ea9a99ae9b5e401fa880cb62a1b274d5b7473b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CAST_SENDER_CAST_PLATFORM_CLIENT_H_
#define CAST_SENDER_CAST_PLATFORM_CLIENT_H_

#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "absl/types/optional.h"
#include "cast/common/channel/cast_message_handler.h"
#include "cast/sender/channel/message_util.h"
#include "util/alarm.h"
#include "util/json/json_value.h"

namespace openscreen {
namespace cast {

struct ServiceInfo;
class VirtualConnectionRouter;

// This class handles Cast messages that generally relate to the "platform", in
// other words not a specific app currently running (e.g. app availability,
// receiver status).  These messages follow a request/response format, so each
// request requires a corresponding response callback.  These requests will also
// timeout if there is no response after a certain amount of time (currently 5
// seconds).  The timeout callbacks will be called on the thread managed by
// |task_runner|.
class CastPlatformClient final : public CastMessageHandler {
 public:
  using AppAvailabilityCallback =
      std::function<void(const std::string& app_id, AppAvailabilityResult)>;

  CastPlatformClient(VirtualConnectionRouter* router,
                     ClockNowFunctionPtr clock,
                     TaskRunner* task_runner);
  ~CastPlatformClient() override;

  // Requests availability information for |app_id| from the receiver identified
  // by |device_id|.  |callback| will be called exactly once with a result.
  absl::optional<int> RequestAppAvailability(const std::string& device_id,
                                             const std::string& app_id,
                                             AppAvailabilityCallback callback);

  // Notifies this object about general receiver connectivity or property
  // changes.
  void AddOrUpdateReceiver(const ServiceInfo& device, int socket_id);
  void RemoveReceiver(const ServiceInfo& device);

  void CancelRequest(int request_id);

 private:
  struct AvailabilityRequest {
    int request_id;
    std::string app_id;
    std::unique_ptr<Alarm> timeout;
    AppAvailabilityCallback callback;
  };

  struct PendingRequests {
    std::vector<AvailabilityRequest> availability;
  };

  // CastMessageHandler overrides.
  void OnMessage(VirtualConnectionRouter* router,
                 CastSocket* socket,
                 ::cast::channel::CastMessage message) override;

  void HandleResponse(const std::string& device_id,
                      int request_id,
                      const Json::Value& message);

  void CancelAppAvailabilityRequest(int request_id);

  static int GetNextRequestId();

  static int next_request_id_;

  const std::string sender_id_;
  VirtualConnectionRouter* const virtual_conn_router_;
  std::map<std::string /* device_id */, int> socket_id_by_device_id_;
  std::map<std::string /* device_id */, PendingRequests>
      pending_requests_by_device_id_;

  const ClockNowFunctionPtr clock_;
  TaskRunner* const task_runner_;
};

}  // namespace cast
}  // namespace openscreen

#endif  // CAST_SENDER_CAST_PLATFORM_CLIENT_H_