xref: /aosp_15_r20/external/openscreen/osp/public/presentation/presentation_receiver.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
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 OSP_PUBLIC_PRESENTATION_PRESENTATION_RECEIVER_H_
6 #define OSP_PUBLIC_PRESENTATION_PRESENTATION_RECEIVER_H_
7 
8 #include <map>
9 #include <memory>
10 #include <string>
11 #include <vector>
12 
13 #include "osp/msgs/osp_messages.h"
14 #include "osp/public/message_demuxer.h"
15 #include "osp/public/presentation/presentation_connection.h"
16 
17 namespace openscreen {
18 namespace osp {
19 
20 enum class ResponseResult {
21   kSuccess = 0,
22   kInvalidUrl,
23   kRequestTimedOut,
24   kRequestFailedTransient,
25   kRequestFailedPermanent,
26   kHttpError,
27   kUnknown,
28 };
29 
30 class ReceiverDelegate {
31  public:
32   virtual ~ReceiverDelegate() = default;
33 
34   // Called when the availability (compatible, not compatible, or invalid)
35   // for specific URLs is needed to be supplied by the delegate.
36   // See "#presentation-protocol" spec section.
37   // Returns a list of url availabilities.
38   virtual std::vector<msgs::UrlAvailability> OnUrlAvailabilityRequest(
39       uint64_t watch_id,
40       uint64_t watch_duration,
41       std::vector<std::string> urls) = 0;
42 
43   // Called when a new presentation is requested by a controller.  This should
44   // return true if the presentation was accepted, false otherwise.
45   virtual bool StartPresentation(
46       const Connection::PresentationInfo& info,
47       uint64_t source_id,
48       const std::vector<msgs::HttpHeader>& http_headers) = 0;
49 
50   // Called when the receiver wants to actually connection to the presentation.
51   // Should return true if the connection was successful, false otherwise.
52   virtual bool ConnectToPresentation(uint64_t request_id,
53                                      const std::string& id,
54                                      uint64_t source_id) = 0;
55 
56   // Called when a presentation is requested to be terminated by a controller.
57   virtual void TerminatePresentation(const std::string& id,
58                                      TerminationReason reason) = 0;
59 };
60 
61 class Receiver final : public MessageDemuxer::MessageCallback,
62                        public Connection::ParentDelegate {
63  public:
64   // TODO(crbug.com/openscreen/31): Remove singletons in the embedder API and
65   // protocol implementation layers.
66   static Receiver* Get();
67   void Init();
68   void Deinit();
69 
70   // Sets the object to call when a new receiver connection is available.
71   // |delegate| must either outlive PresentationReceiver or live until a new
72   // delegate (possibly nullptr) is set.  Setting the delegate to nullptr will
73   // automatically ignore all future receiver requests.
74   void SetReceiverDelegate(ReceiverDelegate* delegate);
75 
76   // Called by the embedder to report its response to StartPresentation.
77   Error OnPresentationStarted(const std::string& presentation_id,
78                               Connection* connection,
79                               ResponseResult result);
80 
81   Error OnConnectionCreated(uint64_t request_id,
82                             Connection* connection,
83                             ResponseResult result);
84 
85   // Connection::ParentDelegate overrides.
86   Error CloseConnection(Connection* connection,
87                         Connection::CloseReason reason) override;
88   // Also called by the embedder to report that a presentation has been
89   // terminated.
90   Error OnPresentationTerminated(const std::string& presentation_id,
91                                  TerminationReason reason) override;
92   void OnConnectionDestroyed(Connection* connection) override;
93 
94   // MessageDemuxer::MessageCallback overrides.
95   ErrorOr<size_t> OnStreamMessage(uint64_t endpoint_id,
96                                   uint64_t connection_id,
97                                   msgs::Type message_type,
98                                   const uint8_t* buffer,
99                                   size_t buffer_size,
100                                   Clock::time_point now) override;
101 
102  private:
103   struct QueuedResponse {
104     enum class Type { kInitiation, kConnection };
105 
106     Type type;
107     uint64_t request_id;
108     uint64_t connection_id;
109     uint64_t endpoint_id;
110   };
111 
112   struct Presentation {
113     uint64_t endpoint_id;
114     MessageDemuxer::MessageWatch terminate_watch;
115     uint64_t terminate_request_id;
116     std::vector<Connection*> connections;
117   };
118 
119   Receiver();
120   ~Receiver() override;
121 
122   using QueuedResponseIterator = std::vector<QueuedResponse>::const_iterator;
123 
124   void DeleteQueuedResponse(const std::string& presentation_id,
125                             QueuedResponseIterator response);
126   ErrorOr<QueuedResponseIterator> GetQueuedResponse(
127       const std::string& presentation_id,
128       uint64_t request_id) const;
129 
130   ReceiverDelegate* delegate_ = nullptr;
131 
132   // TODO(jophba): scope requests by endpoint, not presentation. This doesn't
133   // work properly for multiple controllers.
134   std::map<std::string, std::vector<QueuedResponse>> queued_responses_;
135 
136   // Presentations are added when the embedder starts the presentation,
137   // and ended when a new receiver delegate is set or when
138   // a presentation is called to be terminated (OnPresentationTerminated).
139   std::map<std::string, Presentation> started_presentations_;
140 
141   std::unique_ptr<ConnectionManager> connection_manager_;
142 
143   MessageDemuxer::MessageWatch availability_watch_;
144   MessageDemuxer::MessageWatch initiation_watch_;
145   MessageDemuxer::MessageWatch connection_watch_;
146 
147   uint64_t GetNextConnectionId();
148 };
149 
150 }  // namespace osp
151 }  // namespace openscreen
152 
153 #endif  // OSP_PUBLIC_PRESENTATION_PRESENTATION_RECEIVER_H_
154