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