xref: /aosp_15_r20/external/openscreen/osp/public/presentation/presentation_connection.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #ifndef OSP_PUBLIC_PRESENTATION_PRESENTATION_CONNECTION_H_
6*3f982cf4SFabien Sanglard #define OSP_PUBLIC_PRESENTATION_PRESENTATION_CONNECTION_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <cstdint>
9*3f982cf4SFabien Sanglard #include <map>
10*3f982cf4SFabien Sanglard #include <memory>
11*3f982cf4SFabien Sanglard #include <string>
12*3f982cf4SFabien Sanglard #include <vector>
13*3f982cf4SFabien Sanglard 
14*3f982cf4SFabien Sanglard #include "absl/strings/string_view.h"
15*3f982cf4SFabien Sanglard #include "absl/types/optional.h"
16*3f982cf4SFabien Sanglard #include "osp/public/message_demuxer.h"
17*3f982cf4SFabien Sanglard #include "platform/api/time.h"
18*3f982cf4SFabien Sanglard #include "platform/base/error.h"
19*3f982cf4SFabien Sanglard #include "platform/base/ip_address.h"
20*3f982cf4SFabien Sanglard #include "platform/base/macros.h"
21*3f982cf4SFabien Sanglard #include "util/osp_logging.h"
22*3f982cf4SFabien Sanglard 
23*3f982cf4SFabien Sanglard namespace openscreen {
24*3f982cf4SFabien Sanglard namespace osp {
25*3f982cf4SFabien Sanglard 
26*3f982cf4SFabien Sanglard class ProtocolConnection;
27*3f982cf4SFabien Sanglard 
28*3f982cf4SFabien Sanglard enum class TerminationReason {
29*3f982cf4SFabien Sanglard   kReceiverTerminateCalled = 0,
30*3f982cf4SFabien Sanglard   kReceiverUserTerminated,
31*3f982cf4SFabien Sanglard   kControllerTerminateCalled,
32*3f982cf4SFabien Sanglard   kControllerUserTerminated,
33*3f982cf4SFabien Sanglard   kReceiverPresentationReplaced,
34*3f982cf4SFabien Sanglard   kReceiverIdleTooLong,
35*3f982cf4SFabien Sanglard   kReceiverPresentationUnloaded,
36*3f982cf4SFabien Sanglard   kReceiverShuttingDown,
37*3f982cf4SFabien Sanglard   kReceiverError,
38*3f982cf4SFabien Sanglard };
39*3f982cf4SFabien Sanglard 
40*3f982cf4SFabien Sanglard class Connection {
41*3f982cf4SFabien Sanglard  public:
42*3f982cf4SFabien Sanglard   enum class CloseReason {
43*3f982cf4SFabien Sanglard     kClosed = 0,
44*3f982cf4SFabien Sanglard     kDiscarded,
45*3f982cf4SFabien Sanglard     kError,
46*3f982cf4SFabien Sanglard   };
47*3f982cf4SFabien Sanglard 
48*3f982cf4SFabien Sanglard   enum class State {
49*3f982cf4SFabien Sanglard     // The library is currently attempting to connect to the presentation.
50*3f982cf4SFabien Sanglard     kConnecting,
51*3f982cf4SFabien Sanglard     // The connection to the presentation is open and communication is possible.
52*3f982cf4SFabien Sanglard     kConnected,
53*3f982cf4SFabien Sanglard     // The connection is closed or could not be opened.  No communication is
54*3f982cf4SFabien Sanglard     // possible but it may be possible to reopen the connection via
55*3f982cf4SFabien Sanglard     // ReconnectPresentation.
56*3f982cf4SFabien Sanglard     kClosed,
57*3f982cf4SFabien Sanglard     // The connection is closed and the receiver has been terminated.
58*3f982cf4SFabien Sanglard     kTerminated,
59*3f982cf4SFabien Sanglard   };
60*3f982cf4SFabien Sanglard 
61*3f982cf4SFabien Sanglard   // An object to receive callbacks related to a single Connection.
62*3f982cf4SFabien Sanglard   class Delegate {
63*3f982cf4SFabien Sanglard    public:
64*3f982cf4SFabien Sanglard     Delegate() = default;
65*3f982cf4SFabien Sanglard 
66*3f982cf4SFabien Sanglard     // State changes.
67*3f982cf4SFabien Sanglard     virtual void OnConnected() = 0;
68*3f982cf4SFabien Sanglard 
69*3f982cf4SFabien Sanglard     // Explicit close by other endpoint.
70*3f982cf4SFabien Sanglard     virtual void OnClosedByRemote() = 0;
71*3f982cf4SFabien Sanglard 
72*3f982cf4SFabien Sanglard     // Closed because the script connection object was discarded.
73*3f982cf4SFabien Sanglard     virtual void OnDiscarded() = 0;
74*3f982cf4SFabien Sanglard 
75*3f982cf4SFabien Sanglard     // Closed because of an error.
76*3f982cf4SFabien Sanglard     virtual void OnError(const absl::string_view message) = 0;
77*3f982cf4SFabien Sanglard 
78*3f982cf4SFabien Sanglard     // Terminated through a different connection.
79*3f982cf4SFabien Sanglard     virtual void OnTerminated() = 0;
80*3f982cf4SFabien Sanglard 
81*3f982cf4SFabien Sanglard     // A UTF-8 string message was received.
82*3f982cf4SFabien Sanglard     virtual void OnStringMessage(const absl::string_view message) = 0;
83*3f982cf4SFabien Sanglard 
84*3f982cf4SFabien Sanglard     // A binary message was received.
85*3f982cf4SFabien Sanglard     virtual void OnBinaryMessage(const std::vector<uint8_t>& data) = 0;
86*3f982cf4SFabien Sanglard 
87*3f982cf4SFabien Sanglard    protected:
88*3f982cf4SFabien Sanglard     virtual ~Delegate() = default;
89*3f982cf4SFabien Sanglard 
90*3f982cf4SFabien Sanglard    private:
91*3f982cf4SFabien Sanglard     OSP_DISALLOW_COPY_AND_ASSIGN(Delegate);
92*3f982cf4SFabien Sanglard   };
93*3f982cf4SFabien Sanglard 
94*3f982cf4SFabien Sanglard   // Allows different close, termination, and destruction behavior for both
95*3f982cf4SFabien Sanglard   // possible parents: controller and receiver.  This is different from the
96*3f982cf4SFabien Sanglard   // normal delegate above, which would be supplied by the embedder to link it's
97*3f982cf4SFabien Sanglard   // presentation connection functionality.
98*3f982cf4SFabien Sanglard   class ParentDelegate {
99*3f982cf4SFabien Sanglard    public:
100*3f982cf4SFabien Sanglard     ParentDelegate() = default;
101*3f982cf4SFabien Sanglard     virtual ~ParentDelegate() = default;
102*3f982cf4SFabien Sanglard 
103*3f982cf4SFabien Sanglard     virtual Error CloseConnection(Connection* connection,
104*3f982cf4SFabien Sanglard                                   CloseReason reason) = 0;
105*3f982cf4SFabien Sanglard     virtual Error OnPresentationTerminated(const std::string& presentation_id,
106*3f982cf4SFabien Sanglard                                            TerminationReason reason) = 0;
107*3f982cf4SFabien Sanglard     virtual void OnConnectionDestroyed(Connection* connection) = 0;
108*3f982cf4SFabien Sanglard 
109*3f982cf4SFabien Sanglard    private:
110*3f982cf4SFabien Sanglard     OSP_DISALLOW_COPY_AND_ASSIGN(ParentDelegate);
111*3f982cf4SFabien Sanglard   };
112*3f982cf4SFabien Sanglard 
113*3f982cf4SFabien Sanglard   struct PresentationInfo {
114*3f982cf4SFabien Sanglard     std::string id;
115*3f982cf4SFabien Sanglard     std::string url;
116*3f982cf4SFabien Sanglard   };
117*3f982cf4SFabien Sanglard 
118*3f982cf4SFabien Sanglard   // Constructs a new connection using |delegate| for callbacks.
119*3f982cf4SFabien Sanglard   Connection(const PresentationInfo& info,
120*3f982cf4SFabien Sanglard              Delegate* delegate,
121*3f982cf4SFabien Sanglard              ParentDelegate* parent_delegate);
122*3f982cf4SFabien Sanglard   ~Connection();
123*3f982cf4SFabien Sanglard 
124*3f982cf4SFabien Sanglard   // Returns the ID and URL of this presentation.
presentation_info()125*3f982cf4SFabien Sanglard   const PresentationInfo& presentation_info() const { return presentation_; }
126*3f982cf4SFabien Sanglard 
state()127*3f982cf4SFabien Sanglard   State state() const { return state_; }
128*3f982cf4SFabien Sanglard 
get_protocol_connection()129*3f982cf4SFabien Sanglard   ProtocolConnection* get_protocol_connection() const {
130*3f982cf4SFabien Sanglard     return protocol_connection_.get();
131*3f982cf4SFabien Sanglard   }
132*3f982cf4SFabien Sanglard 
133*3f982cf4SFabien Sanglard   // These methods should only be called when we are connected.
endpoint_id()134*3f982cf4SFabien Sanglard   uint64_t endpoint_id() const {
135*3f982cf4SFabien Sanglard     OSP_CHECK(endpoint_id_);
136*3f982cf4SFabien Sanglard     return endpoint_id_.value();
137*3f982cf4SFabien Sanglard   }
connection_id()138*3f982cf4SFabien Sanglard   uint64_t connection_id() const {
139*3f982cf4SFabien Sanglard     OSP_CHECK(connection_id_);
140*3f982cf4SFabien Sanglard     return connection_id_.value();
141*3f982cf4SFabien Sanglard   }
142*3f982cf4SFabien Sanglard 
143*3f982cf4SFabien Sanglard   // Sends a UTF-8 string message.
144*3f982cf4SFabien Sanglard   Error SendString(absl::string_view message);
145*3f982cf4SFabien Sanglard 
146*3f982cf4SFabien Sanglard   // Sends a binary message.
147*3f982cf4SFabien Sanglard   Error SendBinary(std::vector<uint8_t>&& data);
148*3f982cf4SFabien Sanglard 
149*3f982cf4SFabien Sanglard   // Closes the connection.  This can be based on an explicit request from the
150*3f982cf4SFabien Sanglard   // embedder or because the connection object is being discarded (page
151*3f982cf4SFabien Sanglard   // navigated, object GC'd, etc.).
152*3f982cf4SFabien Sanglard   Error Close(CloseReason reason);
153*3f982cf4SFabien Sanglard 
154*3f982cf4SFabien Sanglard   // Terminates the presentation associated with this connection.
155*3f982cf4SFabien Sanglard   void Terminate(TerminationReason reason);
156*3f982cf4SFabien Sanglard 
157*3f982cf4SFabien Sanglard   void OnConnecting();
158*3f982cf4SFabien Sanglard 
159*3f982cf4SFabien Sanglard   // Called by the receiver when the OnPresentationStarted logic happens. This
160*3f982cf4SFabien Sanglard   // notifies the delegate and updates our internal stream and ids.
161*3f982cf4SFabien Sanglard   void OnConnected(uint64_t connection_id,
162*3f982cf4SFabien Sanglard                    uint64_t endpoint_id,
163*3f982cf4SFabien Sanglard                    std::unique_ptr<ProtocolConnection> stream);
164*3f982cf4SFabien Sanglard 
165*3f982cf4SFabien Sanglard   void OnClosedByError(Error cause);
166*3f982cf4SFabien Sanglard   void OnClosedByRemote();
167*3f982cf4SFabien Sanglard   void OnTerminated();
168*3f982cf4SFabien Sanglard 
get_delegate()169*3f982cf4SFabien Sanglard   Delegate* get_delegate() { return delegate_; }
170*3f982cf4SFabien Sanglard 
171*3f982cf4SFabien Sanglard  private:
172*3f982cf4SFabien Sanglard   // Helper method that handles closing down our internal state.
173*3f982cf4SFabien Sanglard   // Returns whether or not the connection state changed (and thus
174*3f982cf4SFabien Sanglard   // whether or not delegates should be informed).
175*3f982cf4SFabien Sanglard   bool OnClosed();
176*3f982cf4SFabien Sanglard 
177*3f982cf4SFabien Sanglard   PresentationInfo presentation_;
178*3f982cf4SFabien Sanglard   State state_ = State::kConnecting;
179*3f982cf4SFabien Sanglard   Delegate* delegate_;
180*3f982cf4SFabien Sanglard   ParentDelegate* parent_delegate_;
181*3f982cf4SFabien Sanglard   absl::optional<uint64_t> connection_id_;
182*3f982cf4SFabien Sanglard   absl::optional<uint64_t> endpoint_id_;
183*3f982cf4SFabien Sanglard   std::unique_ptr<ProtocolConnection> protocol_connection_;
184*3f982cf4SFabien Sanglard 
185*3f982cf4SFabien Sanglard   OSP_DISALLOW_COPY_AND_ASSIGN(Connection);
186*3f982cf4SFabien Sanglard };
187*3f982cf4SFabien Sanglard 
188*3f982cf4SFabien Sanglard class ConnectionManager final : public MessageDemuxer::MessageCallback {
189*3f982cf4SFabien Sanglard  public:
190*3f982cf4SFabien Sanglard   explicit ConnectionManager(MessageDemuxer* demuxer);
191*3f982cf4SFabien Sanglard 
192*3f982cf4SFabien Sanglard   void AddConnection(Connection* connection);
193*3f982cf4SFabien Sanglard   void RemoveConnection(Connection* connection);
194*3f982cf4SFabien Sanglard 
195*3f982cf4SFabien Sanglard   // MessasgeDemuxer::MessageCallback overrides.
196*3f982cf4SFabien Sanglard   ErrorOr<size_t> OnStreamMessage(uint64_t endpoint_id,
197*3f982cf4SFabien Sanglard                                   uint64_t connection_id,
198*3f982cf4SFabien Sanglard                                   msgs::Type message_type,
199*3f982cf4SFabien Sanglard                                   const uint8_t* buffer,
200*3f982cf4SFabien Sanglard                                   size_t buffer_size,
201*3f982cf4SFabien Sanglard                                   Clock::time_point now) override;
202*3f982cf4SFabien Sanglard 
203*3f982cf4SFabien Sanglard   Connection* GetConnection(uint64_t connection_id);
204*3f982cf4SFabien Sanglard 
205*3f982cf4SFabien Sanglard  private:
206*3f982cf4SFabien Sanglard   // TODO(btolsch): Connection IDs were changed to be per-endpoint, but this
207*3f982cf4SFabien Sanglard   // table then needs to be <endpoint id, connection id> since connection id is
208*3f982cf4SFabien Sanglard   // still not unique globally.
209*3f982cf4SFabien Sanglard   std::map<uint64_t, Connection*> connections_;
210*3f982cf4SFabien Sanglard 
211*3f982cf4SFabien Sanglard   MessageDemuxer::MessageWatch message_watch_;
212*3f982cf4SFabien Sanglard   MessageDemuxer::MessageWatch close_request_watch_;
213*3f982cf4SFabien Sanglard   MessageDemuxer::MessageWatch close_event_watch_;
214*3f982cf4SFabien Sanglard 
215*3f982cf4SFabien Sanglard   OSP_DISALLOW_COPY_AND_ASSIGN(ConnectionManager);
216*3f982cf4SFabien Sanglard };
217*3f982cf4SFabien Sanglard 
218*3f982cf4SFabien Sanglard }  // namespace osp
219*3f982cf4SFabien Sanglard }  // namespace openscreen
220*3f982cf4SFabien Sanglard 
221*3f982cf4SFabien Sanglard #endif  // OSP_PUBLIC_PRESENTATION_PRESENTATION_CONNECTION_H_
222