xref: /aosp_15_r20/external/openscreen/osp/public/presentation/presentation_controller.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2018 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_CONTROLLER_H_
6*3f982cf4SFabien Sanglard #define OSP_PUBLIC_PRESENTATION_PRESENTATION_CONTROLLER_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <map>
9*3f982cf4SFabien Sanglard #include <memory>
10*3f982cf4SFabien Sanglard #include <string>
11*3f982cf4SFabien Sanglard 
12*3f982cf4SFabien Sanglard #include "absl/strings/string_view.h"
13*3f982cf4SFabien Sanglard #include "absl/types/optional.h"
14*3f982cf4SFabien Sanglard #include "osp/public/presentation/presentation_connection.h"
15*3f982cf4SFabien Sanglard #include "osp/public/protocol_connection.h"
16*3f982cf4SFabien Sanglard #include "osp/public/service_listener.h"
17*3f982cf4SFabien Sanglard #include "platform/api/time.h"
18*3f982cf4SFabien Sanglard #include "platform/base/error.h"
19*3f982cf4SFabien Sanglard 
20*3f982cf4SFabien Sanglard namespace openscreen {
21*3f982cf4SFabien Sanglard namespace osp {
22*3f982cf4SFabien Sanglard 
23*3f982cf4SFabien Sanglard class UrlAvailabilityRequester;
24*3f982cf4SFabien Sanglard 
25*3f982cf4SFabien Sanglard class RequestDelegate {
26*3f982cf4SFabien Sanglard  public:
27*3f982cf4SFabien Sanglard   virtual ~RequestDelegate() = default;
28*3f982cf4SFabien Sanglard 
29*3f982cf4SFabien Sanglard   virtual void OnConnection(std::unique_ptr<Connection> connection) = 0;
30*3f982cf4SFabien Sanglard   virtual void OnError(const Error& error) = 0;
31*3f982cf4SFabien Sanglard };
32*3f982cf4SFabien Sanglard 
33*3f982cf4SFabien Sanglard class ReceiverObserver {
34*3f982cf4SFabien Sanglard  public:
35*3f982cf4SFabien Sanglard   virtual ~ReceiverObserver() = default;
36*3f982cf4SFabien Sanglard 
37*3f982cf4SFabien Sanglard   // Called when there is an unrecoverable error in requesting availability.
38*3f982cf4SFabien Sanglard   // This means the availability is unknown and there is no further response to
39*3f982cf4SFabien Sanglard   // wait for.
40*3f982cf4SFabien Sanglard   virtual void OnRequestFailed(const std::string& presentation_url,
41*3f982cf4SFabien Sanglard                                const std::string& service_id) = 0;
42*3f982cf4SFabien Sanglard 
43*3f982cf4SFabien Sanglard   // Called when receivers compatible with |presentation_url| are known to be
44*3f982cf4SFabien Sanglard   // available.
45*3f982cf4SFabien Sanglard   virtual void OnReceiverAvailable(const std::string& presentation_url,
46*3f982cf4SFabien Sanglard                                    const std::string& service_id) = 0;
47*3f982cf4SFabien Sanglard   // Only called for |service_id| values previously advertised as available.
48*3f982cf4SFabien Sanglard   virtual void OnReceiverUnavailable(const std::string& presentation_url,
49*3f982cf4SFabien Sanglard                                      const std::string& service_id) = 0;
50*3f982cf4SFabien Sanglard };
51*3f982cf4SFabien Sanglard 
52*3f982cf4SFabien Sanglard class Controller final : public ServiceListener::Observer,
53*3f982cf4SFabien Sanglard                          public Connection::ParentDelegate {
54*3f982cf4SFabien Sanglard  public:
55*3f982cf4SFabien Sanglard   class ReceiverWatch {
56*3f982cf4SFabien Sanglard    public:
57*3f982cf4SFabien Sanglard     ReceiverWatch();
58*3f982cf4SFabien Sanglard     ReceiverWatch(Controller* controller,
59*3f982cf4SFabien Sanglard                   const std::vector<std::string>& urls,
60*3f982cf4SFabien Sanglard                   ReceiverObserver* observer);
61*3f982cf4SFabien Sanglard     ReceiverWatch(ReceiverWatch&&) noexcept;
62*3f982cf4SFabien Sanglard     ~ReceiverWatch();
63*3f982cf4SFabien Sanglard 
64*3f982cf4SFabien Sanglard     ReceiverWatch& operator=(ReceiverWatch);
65*3f982cf4SFabien Sanglard 
66*3f982cf4SFabien Sanglard     explicit operator bool() const { return observer_; }
67*3f982cf4SFabien Sanglard 
68*3f982cf4SFabien Sanglard     friend void swap(ReceiverWatch& a, ReceiverWatch& b);
69*3f982cf4SFabien Sanglard 
70*3f982cf4SFabien Sanglard    private:
71*3f982cf4SFabien Sanglard     std::vector<std::string> urls_;
72*3f982cf4SFabien Sanglard     ReceiverObserver* observer_ = nullptr;
73*3f982cf4SFabien Sanglard     Controller* controller_ = nullptr;
74*3f982cf4SFabien Sanglard   };
75*3f982cf4SFabien Sanglard 
76*3f982cf4SFabien Sanglard   class ConnectRequest {
77*3f982cf4SFabien Sanglard    public:
78*3f982cf4SFabien Sanglard     ConnectRequest();
79*3f982cf4SFabien Sanglard     ConnectRequest(Controller* controller,
80*3f982cf4SFabien Sanglard                    const std::string& service_id,
81*3f982cf4SFabien Sanglard                    bool is_reconnect,
82*3f982cf4SFabien Sanglard                    absl::optional<uint64_t> request_id);
83*3f982cf4SFabien Sanglard     ConnectRequest(ConnectRequest&&) noexcept;
84*3f982cf4SFabien Sanglard     ~ConnectRequest();
85*3f982cf4SFabien Sanglard 
86*3f982cf4SFabien Sanglard     ConnectRequest& operator=(ConnectRequest);
87*3f982cf4SFabien Sanglard 
88*3f982cf4SFabien Sanglard     explicit operator bool() const { return request_id_.has_value(); }
89*3f982cf4SFabien Sanglard 
90*3f982cf4SFabien Sanglard     friend void swap(ConnectRequest& a, ConnectRequest& b);
91*3f982cf4SFabien Sanglard 
92*3f982cf4SFabien Sanglard    private:
93*3f982cf4SFabien Sanglard     std::string service_id_;
94*3f982cf4SFabien Sanglard     bool is_reconnect_;
95*3f982cf4SFabien Sanglard     absl::optional<uint64_t> request_id_;
96*3f982cf4SFabien Sanglard     Controller* controller_;
97*3f982cf4SFabien Sanglard   };
98*3f982cf4SFabien Sanglard 
99*3f982cf4SFabien Sanglard   explicit Controller(ClockNowFunctionPtr now_function);
100*3f982cf4SFabien Sanglard   ~Controller();
101*3f982cf4SFabien Sanglard 
102*3f982cf4SFabien Sanglard   // Requests receivers compatible with all urls in |urls| and registers
103*3f982cf4SFabien Sanglard   // |observer| for availability changes.  The screens will be a subset of the
104*3f982cf4SFabien Sanglard   // screen list maintained by the ServiceListener.  Returns an RAII object that
105*3f982cf4SFabien Sanglard   // tracks the registration.
106*3f982cf4SFabien Sanglard   ReceiverWatch RegisterReceiverWatch(const std::vector<std::string>& urls,
107*3f982cf4SFabien Sanglard                                       ReceiverObserver* observer);
108*3f982cf4SFabien Sanglard 
109*3f982cf4SFabien Sanglard   // Requests that a new presentation be created on |service_id| using
110*3f982cf4SFabien Sanglard   // |presentation_url|, with the result passed to |delegate|.
111*3f982cf4SFabien Sanglard   // |conn_delegate| is passed to the resulting connection.  The returned
112*3f982cf4SFabien Sanglard   // ConnectRequest object may be destroyed before any |delegate| methods are
113*3f982cf4SFabien Sanglard   // called to cancel the request.
114*3f982cf4SFabien Sanglard   ConnectRequest StartPresentation(const std::string& url,
115*3f982cf4SFabien Sanglard                                    const std::string& service_id,
116*3f982cf4SFabien Sanglard                                    RequestDelegate* delegate,
117*3f982cf4SFabien Sanglard                                    Connection::Delegate* conn_delegate);
118*3f982cf4SFabien Sanglard 
119*3f982cf4SFabien Sanglard   // Requests reconnection to the presentation with the given id and URL running
120*3f982cf4SFabien Sanglard   // on |service_id|, with the result passed to |delegate|.  |conn_delegate| is
121*3f982cf4SFabien Sanglard   // passed to the resulting connection.  The returned ConnectRequest object may
122*3f982cf4SFabien Sanglard   // be destroyed before any |delegate| methods are called to cancel the
123*3f982cf4SFabien Sanglard   // request.
124*3f982cf4SFabien Sanglard   ConnectRequest ReconnectPresentation(const std::vector<std::string>& urls,
125*3f982cf4SFabien Sanglard                                        const std::string& presentation_id,
126*3f982cf4SFabien Sanglard                                        const std::string& service_id,
127*3f982cf4SFabien Sanglard                                        RequestDelegate* delegate,
128*3f982cf4SFabien Sanglard                                        Connection::Delegate* conn_delegate);
129*3f982cf4SFabien Sanglard 
130*3f982cf4SFabien Sanglard   // Requests reconnection with a previously-connected connection.  This both
131*3f982cf4SFabien Sanglard   // avoids having to respecify the parameters and connection delegate but also
132*3f982cf4SFabien Sanglard   // simplifies the implementation of the Presentation API requirement to return
133*3f982cf4SFabien Sanglard   // the same connection object where possible.
134*3f982cf4SFabien Sanglard   ConnectRequest ReconnectConnection(std::unique_ptr<Connection> connection,
135*3f982cf4SFabien Sanglard                                      RequestDelegate* delegate);
136*3f982cf4SFabien Sanglard 
137*3f982cf4SFabien Sanglard   // Connection::ParentDelegate overrides.
138*3f982cf4SFabien Sanglard   Error CloseConnection(Connection* connection,
139*3f982cf4SFabien Sanglard                         Connection::CloseReason reason) override;
140*3f982cf4SFabien Sanglard 
141*3f982cf4SFabien Sanglard   // Also called by the embedder to report that a presentation has been
142*3f982cf4SFabien Sanglard   // terminated.
143*3f982cf4SFabien Sanglard   Error OnPresentationTerminated(const std::string& presentation_id,
144*3f982cf4SFabien Sanglard                                  TerminationReason reason) override;
145*3f982cf4SFabien Sanglard 
146*3f982cf4SFabien Sanglard   void OnConnectionDestroyed(Connection* connection) override;
147*3f982cf4SFabien Sanglard 
148*3f982cf4SFabien Sanglard   // Returns an empty string if no such presentation ID is found.
149*3f982cf4SFabien Sanglard   std::string GetServiceIdForPresentationId(
150*3f982cf4SFabien Sanglard       const std::string& presentation_id) const;
151*3f982cf4SFabien Sanglard 
152*3f982cf4SFabien Sanglard   ProtocolConnection* GetConnectionRequestGroupStream(
153*3f982cf4SFabien Sanglard       const std::string& service_id);
154*3f982cf4SFabien Sanglard 
155*3f982cf4SFabien Sanglard   // TODO(btolsch): still used?
156*3f982cf4SFabien Sanglard   void SetConnectionRequestGroupStreamForTest(
157*3f982cf4SFabien Sanglard       const std::string& service_id,
158*3f982cf4SFabien Sanglard       std::unique_ptr<ProtocolConnection> stream);
159*3f982cf4SFabien Sanglard 
160*3f982cf4SFabien Sanglard  private:
161*3f982cf4SFabien Sanglard   class TerminationListener;
162*3f982cf4SFabien Sanglard   class MessageGroupStreams;
163*3f982cf4SFabien Sanglard 
164*3f982cf4SFabien Sanglard   struct ControlledPresentation {
165*3f982cf4SFabien Sanglard     std::string service_id;
166*3f982cf4SFabien Sanglard     std::string url;
167*3f982cf4SFabien Sanglard     std::vector<Connection*> connections;
168*3f982cf4SFabien Sanglard   };
169*3f982cf4SFabien Sanglard 
170*3f982cf4SFabien Sanglard   static std::string MakePresentationId(const std::string& url,
171*3f982cf4SFabien Sanglard                                         const std::string& service_id);
172*3f982cf4SFabien Sanglard 
173*3f982cf4SFabien Sanglard   void AddConnection(Connection* connection);
174*3f982cf4SFabien Sanglard   void OpenConnection(uint64_t connection_id,
175*3f982cf4SFabien Sanglard                       uint64_t endpoint_id,
176*3f982cf4SFabien Sanglard                       const std::string& service_id,
177*3f982cf4SFabien Sanglard                       RequestDelegate* request_delegate,
178*3f982cf4SFabien Sanglard                       std::unique_ptr<Connection>&& connection,
179*3f982cf4SFabien Sanglard                       std::unique_ptr<ProtocolConnection>&& stream);
180*3f982cf4SFabien Sanglard 
181*3f982cf4SFabien Sanglard   void TerminatePresentationById(const std::string& presentation_id);
182*3f982cf4SFabien Sanglard 
183*3f982cf4SFabien Sanglard   // Cancels compatible receiver monitoring for the given |urls|, |observer|
184*3f982cf4SFabien Sanglard   // pair.
185*3f982cf4SFabien Sanglard   void CancelReceiverWatch(const std::vector<std::string>& urls,
186*3f982cf4SFabien Sanglard                            ReceiverObserver* observer);
187*3f982cf4SFabien Sanglard 
188*3f982cf4SFabien Sanglard   // Cancels a presentation connect request for the given |request_id| if one is
189*3f982cf4SFabien Sanglard   // pending.
190*3f982cf4SFabien Sanglard   void CancelConnectRequest(const std::string& service_id,
191*3f982cf4SFabien Sanglard                             bool is_reconnect,
192*3f982cf4SFabien Sanglard                             uint64_t request_id);
193*3f982cf4SFabien Sanglard 
194*3f982cf4SFabien Sanglard   // ServiceListener::Observer overrides.
195*3f982cf4SFabien Sanglard   void OnStarted() override;
196*3f982cf4SFabien Sanglard   void OnStopped() override;
197*3f982cf4SFabien Sanglard   void OnSuspended() override;
198*3f982cf4SFabien Sanglard   void OnSearching() override;
199*3f982cf4SFabien Sanglard   void OnReceiverAdded(const ServiceInfo& info) override;
200*3f982cf4SFabien Sanglard   void OnReceiverChanged(const ServiceInfo& info) override;
201*3f982cf4SFabien Sanglard   void OnReceiverRemoved(const ServiceInfo& info) override;
202*3f982cf4SFabien Sanglard   void OnAllReceiversRemoved() override;
203*3f982cf4SFabien Sanglard   void OnError(ServiceListenerError) override;
204*3f982cf4SFabien Sanglard   void OnMetrics(ServiceListener::Metrics) override;
205*3f982cf4SFabien Sanglard 
206*3f982cf4SFabien Sanglard   std::map<std::string, uint64_t> next_connection_id_;
207*3f982cf4SFabien Sanglard 
208*3f982cf4SFabien Sanglard   std::map<std::string, ControlledPresentation> presentations_;
209*3f982cf4SFabien Sanglard 
210*3f982cf4SFabien Sanglard   std::unique_ptr<ConnectionManager> connection_manager_;
211*3f982cf4SFabien Sanglard 
212*3f982cf4SFabien Sanglard   std::unique_ptr<UrlAvailabilityRequester> availability_requester_;
213*3f982cf4SFabien Sanglard   std::map<std::string, IPEndpoint> receiver_endpoints_;
214*3f982cf4SFabien Sanglard 
215*3f982cf4SFabien Sanglard   std::map<std::string, std::unique_ptr<MessageGroupStreams>> group_streams_;
216*3f982cf4SFabien Sanglard   std::map<std::string, std::unique_ptr<TerminationListener>>
217*3f982cf4SFabien Sanglard       termination_listener_by_id_;
218*3f982cf4SFabien Sanglard };
219*3f982cf4SFabien Sanglard 
220*3f982cf4SFabien Sanglard }  // namespace osp
221*3f982cf4SFabien Sanglard }  // namespace openscreen
222*3f982cf4SFabien Sanglard 
223*3f982cf4SFabien Sanglard #endif  // OSP_PUBLIC_PRESENTATION_PRESENTATION_CONTROLLER_H_
224